@noodleseed/assistant 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +29 -7
  2. package/dist/{appearance-BLO7kFYB.d.cts → appearance-DowzFJjh.d.cts} +9 -0
  3. package/dist/{appearance-BLO7kFYB.d.ts → appearance-DowzFJjh.d.ts} +9 -0
  4. package/dist/{chunk-N6TFOYOX.js → chunk-GTYYQNGT.js} +71 -5
  5. package/dist/chunk-GTYYQNGT.js.map +1 -0
  6. package/dist/chunk-NSBPE2FW.js +17 -0
  7. package/dist/chunk-NSBPE2FW.js.map +1 -0
  8. package/dist/chunk-UXPKSCID.js +14767 -0
  9. package/dist/chunk-UXPKSCID.js.map +1 -0
  10. package/dist/chunk-ZKXOX67J.js +8002 -0
  11. package/dist/chunk-ZKXOX67J.js.map +1 -0
  12. package/dist/{client-Dd7_LZLY.d.ts → client-9kup0-ws.d.cts} +19 -5
  13. package/dist/{client-Bm990MFE.d.cts → client-BRjZMXlk.d.ts} +19 -5
  14. package/dist/client.cjs +70 -4
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.d.cts +2 -2
  17. package/dist/client.d.ts +2 -2
  18. package/dist/client.js +2 -1
  19. package/dist/index.cjs +19720 -960
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +56 -4
  22. package/dist/index.d.ts +56 -4
  23. package/dist/index.js +4 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/react.cjs +19747 -965
  26. package/dist/react.cjs.map +1 -1
  27. package/dist/react.d.cts +13 -7
  28. package/dist/react.d.ts +13 -7
  29. package/dist/react.js +30 -6
  30. package/dist/react.js.map +1 -1
  31. package/dist/server.d.cts +1 -1
  32. package/dist/server.d.ts +1 -1
  33. package/dist/server.js +2 -0
  34. package/dist/server.js.map +1 -1
  35. package/dist/v4-2UXPDMWJ.js +485 -0
  36. package/dist/v4-2UXPDMWJ.js.map +1 -0
  37. package/package.json +2 -1
  38. package/dist/chunk-N6TFOYOX.js.map +0 -1
  39. package/dist/chunk-QMDSNLTA.js +0 -4459
  40. package/dist/chunk-QMDSNLTA.js.map +0 -1
@@ -1,4459 +0,0 @@
1
- import {
2
- AssistantClientError,
3
- copyAssistantModelContext,
4
- createAssistantClient
5
- } from "./chunk-N6TFOYOX.js";
6
-
7
- // src/appearance.ts
8
- var common = {
9
- fontFamily: "inherit",
10
- monoFontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
11
- baseFontSize: 15,
12
- messageFontSize: 15,
13
- lineHeight: 1.5,
14
- panelRadius: 24,
15
- cardRadius: 16,
16
- inputRadius: 999,
17
- buttonRadius: 999,
18
- launcherRadius: 999,
19
- spacing: 12,
20
- backdropBlur: 18,
21
- motionScale: 1
22
- };
23
- var DEFAULT_APPEARANCE = {
24
- brand: { name: "Assistant", logo: {}, avatar: {}, mark: {} },
25
- theme: {
26
- defaultMode: "auto",
27
- light: {
28
- ...common,
29
- page: "#F8F8F8",
30
- panel: "#F8F8F8",
31
- elevated: "#F4F4F5",
32
- input: "#FFFFFF",
33
- hover: "#F4F4F5",
34
- selected: "#FFF1E7",
35
- text: "#09090B",
36
- mutedText: "#71717A",
37
- accent: "#C2410C",
38
- accentText: "#FFFFFF",
39
- link: "#9A3412",
40
- divider: "#E4E4E7",
41
- focus: "#C2410C",
42
- success: "#16835D",
43
- warning: "#A45B00",
44
- danger: "#C92A45",
45
- overlay: "#18181B66",
46
- code: "#F1F1F3",
47
- widgetFrame: "#E4E4E7",
48
- shadow: "0 4px 16px rgba(0, 0, 0, 0.06), 0 24px 70px rgba(0, 0, 0, 0.10)"
49
- },
50
- dark: {
51
- ...common,
52
- page: "#0C0A09",
53
- panel: "#0C0A09",
54
- elevated: "#27272A",
55
- input: "#1C1917",
56
- hover: "#27272A",
57
- selected: "#431B0B",
58
- text: "#FAFAFA",
59
- mutedText: "#A1A1AA",
60
- accent: "#FB923C",
61
- accentText: "#1C0A02",
62
- link: "#FDBA74",
63
- divider: "#292524",
64
- focus: "#FB923C",
65
- success: "#58C69A",
66
- warning: "#F2B45F",
67
- danger: "#FF8094",
68
- overlay: "#00000099",
69
- code: "#26262C",
70
- widgetFrame: "#34343B",
71
- shadow: "0 8px 32px rgba(0, 0, 0, 0.48)"
72
- }
73
- },
74
- layout: {
75
- mode: "floating",
76
- position: "bottom-right",
77
- panelWidth: 560,
78
- panelMinHeight: 540,
79
- panelMaxHeight: 820,
80
- edgeOffset: 20,
81
- zIndex: 2147483e3,
82
- density: "comfortable",
83
- mobileFullscreen: true
84
- },
85
- behavior: {
86
- startOpen: false,
87
- closeOnEscape: true,
88
- closeOnOutsideClick: false,
89
- showLauncher: true,
90
- showHeader: true,
91
- showAvatars: true,
92
- showTimestamps: false
93
- },
94
- labels: {
95
- welcomeHeading: "How can I help?",
96
- welcomeMessage: "",
97
- composerPlaceholder: "Ask a question\u2026",
98
- thinking: "Thinking",
99
- send: "Send",
100
- stop: "Stop",
101
- close: "Close assistant",
102
- open: "Open assistant",
103
- confirm: "Confirm",
104
- cancel: "Cancel",
105
- retry: "Try again",
106
- unavailable: "The assistant is temporarily unavailable.",
107
- sessionExpired: "Your assistant session expired. Reopen it to continue.",
108
- sessionIdle: "Assistant session idle",
109
- sessionLoading: "Assistant session loading",
110
- sessionReady: "Assistant session ready",
111
- sessionError: "Assistant session unavailable"
112
- },
113
- presentation: {
114
- panel: {
115
- surface: "glass",
116
- elevation: "soft",
117
- border: "subtle"
118
- },
119
- launcher: {
120
- icon: "brand-mark",
121
- size: "md",
122
- status: "none",
123
- effect: "none"
124
- },
125
- header: { mark: "none" },
126
- composer: { leadingIcon: "none", sendIcon: "arrow-up", shape: "pill" },
127
- messages: { userStyle: "bubble", assistantStyle: "plain" }
128
- },
129
- suggestedPrompts: [],
130
- locale: "en",
131
- direction: "auto"
132
- };
133
- function resolveAppearance(input = {}) {
134
- const branding = input.branding;
135
- const assistant = input.assistant;
136
- return {
137
- brand: {
138
- ...DEFAULT_APPEARANCE.brand,
139
- ...branding?.name ? { name: branding.name } : {},
140
- logo: themedAsset(branding?.logo),
141
- avatar: themedAsset(branding?.avatar),
142
- mark: themedAsset(branding?.mark)
143
- },
144
- theme: {
145
- defaultMode: branding?.colorScheme ?? DEFAULT_APPEARANCE.theme.defaultMode,
146
- light: resolveTheme("light", branding),
147
- dark: resolveTheme("dark", branding)
148
- },
149
- layout: {
150
- ...DEFAULT_APPEARANCE.layout,
151
- ...branding?.density ? { density: branding.density } : {},
152
- ...assistant?.layout,
153
- ...assistant?.layout?.edgeOffset === void 0 ? {} : { edgeOffset: boundedNumber(assistant.layout.edgeOffset, 0, 96) }
154
- },
155
- behavior: { ...DEFAULT_APPEARANCE.behavior, ...assistant?.behavior },
156
- labels: { ...DEFAULT_APPEARANCE.labels, ...assistant?.labels },
157
- presentation: resolvePresentation(assistant?.presentation),
158
- suggestedPrompts: assistant?.suggestedPrompts ?? DEFAULT_APPEARANCE.suggestedPrompts,
159
- ...assistant?.privacyUrl ? { privacyUrl: assistant.privacyUrl } : {},
160
- ...assistant?.termsUrl ? { termsUrl: assistant.termsUrl } : {},
161
- locale: assistant?.locale ?? DEFAULT_APPEARANCE.locale,
162
- direction: assistant?.direction ?? DEFAULT_APPEARANCE.direction
163
- };
164
- }
165
- function resolvePresentation(input) {
166
- const defaults = DEFAULT_APPEARANCE.presentation;
167
- const panelRadius = input?.panel?.radius === void 0 ? defaults.panel.radius : boundedNumber(input.panel.radius, 0, 64);
168
- return {
169
- panel: {
170
- ...defaults.panel,
171
- ...input?.panel,
172
- ...panelRadius === void 0 ? {} : { radius: panelRadius }
173
- },
174
- launcher: { ...defaults.launcher, ...input?.launcher },
175
- header: {
176
- mark: input?.header?.mark ?? defaults.header.mark,
177
- ...input?.header?.badge ? {
178
- badge: {
179
- text: input.header.badge.text,
180
- tone: input.header.badge.tone ?? "neutral",
181
- indicator: input.header.badge.indicator ?? false
182
- }
183
- } : {}
184
- },
185
- composer: { ...defaults.composer, ...input?.composer },
186
- messages: { ...defaults.messages, ...input?.messages }
187
- };
188
- }
189
- function boundedNumber(value, min, max) {
190
- return Math.min(max, Math.max(min, Number.isFinite(value) ? Math.round(value) : min));
191
- }
192
- function themedAsset(asset) {
193
- return asset ? { light: asset.uri, dark: asset.darkUri ?? asset.uri } : {};
194
- }
195
- function resolveTheme(mode, branding) {
196
- const defaults = DEFAULT_APPEARANCE.theme[mode];
197
- const surface = mode === "light" ? branding?.surface : branding?.surfaceDark;
198
- const portable = branding?.theme?.[mode];
199
- const configuredAccent = portable?.accent ?? branding?.accent;
200
- const derivedAccentText = configuredAccent && !portable?.accentText ? contrastingText(configuredAccent) : void 0;
201
- const radius = branding?.radius ? radiusValue(branding.radius) : void 0;
202
- return {
203
- ...defaults,
204
- ...branding?.accent ? { accent: branding.accent } : {},
205
- ...surface ? { page: surface, panel: surface } : {},
206
- ...mapPortableTheme(portable),
207
- ...derivedAccentText ? { accentText: derivedAccentText } : {},
208
- ...radius === void 0 ? {} : {
209
- panelRadius: radius,
210
- cardRadius: radius,
211
- inputRadius: Math.max(0, radius - 2),
212
- buttonRadius: Math.max(0, radius - 2)
213
- },
214
- ...branding?.typography === "serif" ? { fontFamily: "ui-serif, Georgia, serif" } : branding?.typography === "mono" ? { fontFamily: defaults.monoFontFamily } : {}
215
- };
216
- }
217
- function contrastingText(background) {
218
- const dark = "#09090B";
219
- const light = "#FFFFFF";
220
- return contrastRatio(background, dark) >= contrastRatio(background, light) ? dark : light;
221
- }
222
- function contrastRatio(first, second) {
223
- const lighter = Math.max(relativeLuminance(first), relativeLuminance(second));
224
- const darker = Math.min(relativeLuminance(first), relativeLuminance(second));
225
- return (lighter + 0.05) / (darker + 0.05);
226
- }
227
- function relativeLuminance(color) {
228
- const match = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
229
- if (!match) return 0;
230
- const channels = match.slice(1).map((channel) => {
231
- const value = Number.parseInt(channel, 16) / 255;
232
- return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
233
- });
234
- return 0.2126 * (channels[0] ?? 0) + 0.7152 * (channels[1] ?? 0) + 0.0722 * (channels[2] ?? 0);
235
- }
236
- function mapPortableTheme(input) {
237
- if (!input) return {};
238
- return {
239
- ...input.surface ? { page: input.surface, panel: input.surface } : {},
240
- ...input.surfaceRaised ? { elevated: input.surfaceRaised } : {},
241
- ...input.surfaceMuted ? { input: input.surfaceMuted, hover: input.surfaceMuted, selected: input.surfaceMuted } : {},
242
- ...input.text ? { text: input.text } : {},
243
- ...input.textMuted ? { mutedText: input.textMuted } : {},
244
- ...input.accent ? { accent: input.accent } : {},
245
- ...input.accentText ? { accentText: input.accentText } : {},
246
- ...input.link ? { link: input.link } : {},
247
- ...input.border ? { divider: input.border, widgetFrame: input.border } : {},
248
- ...input.focus ? { focus: input.focus } : {},
249
- ...input.success ? { success: input.success } : {},
250
- ...input.warning ? { warning: input.warning } : {},
251
- ...input.danger ? { danger: input.danger } : {},
252
- ...input.code ? { code: input.code } : {}
253
- };
254
- }
255
- function radiusValue(radius) {
256
- if (radius === "none") return 0;
257
- if (radius === "sm") return 8;
258
- if (radius === "lg") return 18;
259
- return 14;
260
- }
261
-
262
- // src/browser-context.ts
263
- function browserClientContext() {
264
- let timeZone;
265
- try {
266
- timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
267
- } catch {
268
- }
269
- const locale = globalThis.navigator?.language;
270
- return {
271
- ...locale ? { locale } : {},
272
- ...timeZone ? { timeZone } : {}
273
- };
274
- }
275
-
276
- // src/input-request-card.ts
277
- function createInputRequestCard(options) {
278
- const card = document.createElement("section");
279
- card.className = "tool-proposal input-request";
280
- card.dataset.kind = "input";
281
- const form = document.createElement("form");
282
- const heading = document.createElement("strong");
283
- heading.textContent = options.message;
284
- form.append(heading);
285
- const properties = record(options.requestedSchema.properties);
286
- const required = new Set(
287
- Array.isArray(options.requestedSchema.required) ? options.requestedSchema.required.filter(
288
- (value) => typeof value === "string"
289
- ) : []
290
- );
291
- const controls = /* @__PURE__ */ new Map();
292
- const touched = /* @__PURE__ */ new WeakSet();
293
- for (const [name, rawProperty] of Object.entries(properties)) {
294
- const property = record(rawProperty);
295
- const label = document.createElement("label");
296
- const caption = document.createElement("span");
297
- caption.textContent = typeof property.title === "string" && property.title ? property.title : humanize(name);
298
- const control = createControl(name, property, required.has(name));
299
- const markTouched = () => {
300
- touched.add(control);
301
- updateControlValidity(control, property, required.has(name), touched.has(control));
302
- };
303
- control.addEventListener("input", markTouched);
304
- control.addEventListener("change", markTouched);
305
- label.append(caption, control);
306
- form.append(label);
307
- controls.set(name, control);
308
- }
309
- const actions = document.createElement("div");
310
- actions.className = "proposal-actions";
311
- const submit = button(options.labels.submit, "submit");
312
- const decline = button(options.labels.decline, "button");
313
- const cancel = button(options.labels.cancel, "button");
314
- const buttons = [submit, decline, cancel];
315
- const resolve = async (response) => {
316
- buttons.forEach((item) => {
317
- item.disabled = true;
318
- });
319
- try {
320
- await options.respond(response);
321
- } catch (error) {
322
- buttons.forEach((item) => {
323
- item.disabled = false;
324
- });
325
- throw error;
326
- }
327
- };
328
- form.addEventListener("submit", (event) => {
329
- event.preventDefault();
330
- for (const [name, control] of controls) {
331
- updateControlValidity(
332
- control,
333
- record(properties[name]),
334
- required.has(name),
335
- touched.has(control)
336
- );
337
- }
338
- if (!form.reportValidity()) return;
339
- void resolve({
340
- action: "accept",
341
- content: readContent(controls, properties, required, touched)
342
- }).catch(() => {
343
- });
344
- });
345
- decline.addEventListener("click", () => {
346
- void resolve({ action: "decline" }).catch(() => {
347
- });
348
- });
349
- cancel.addEventListener("click", () => {
350
- void resolve({ action: "cancel" }).catch(() => {
351
- });
352
- });
353
- actions.append(submit, decline, cancel);
354
- form.append(actions);
355
- card.append(form);
356
- return card;
357
- }
358
- function createControl(name, property, required) {
359
- const choices = stringChoices(property);
360
- if (choices || property.type === "array") {
361
- const select = document.createElement("select");
362
- select.name = name;
363
- select.multiple = property.type === "array";
364
- const availableChoices = choices ?? arrayChoices(property);
365
- if (!select.multiple && (!required || !availableChoices.some((choice) => choice.value === property.default))) {
366
- select.append(placeholderOption(availableChoices));
367
- }
368
- for (const choice of availableChoices) {
369
- select.append(option(choice.title, choice.value));
370
- }
371
- applySelectDefault(select, property.default);
372
- updateControlValidity(select, property, required, false);
373
- return select;
374
- }
375
- const input = document.createElement("input");
376
- input.name = name;
377
- input.type = inputType(property);
378
- input.required = required && inputNeedsNonEmptyValue(property);
379
- if (property.type === "integer") input.step = "1";
380
- if (typeof property.minimum === "number") input.min = String(property.minimum);
381
- if (typeof property.maximum === "number") input.max = String(property.maximum);
382
- if (typeof property.minLength === "number") input.minLength = property.minLength;
383
- if (typeof property.maxLength === "number") input.maxLength = property.maxLength;
384
- if (property.format === "date-time") input.step = "0.001";
385
- applyInputDefault(input, property);
386
- return input;
387
- }
388
- function readContent(controls, properties, required, touched) {
389
- const content = {};
390
- for (const [name, control] of controls) {
391
- const property = record(properties[name]);
392
- if (control instanceof HTMLSelectElement && control.multiple) {
393
- const values = [...control.selectedOptions].map((option2) => option2.value);
394
- if (shouldIncludeArray(property, required.has(name), touched.has(control), values.length)) {
395
- content[name] = values;
396
- }
397
- } else if (control instanceof HTMLInputElement && control.type === "checkbox") {
398
- if (required.has(name) || hasDefault(property) || touched.has(control)) {
399
- content[name] = control.checked;
400
- }
401
- } else if (control instanceof HTMLSelectElement) {
402
- if (!isPlaceholderSelected(control)) content[name] = control.value;
403
- } else if (control.value !== "" || property.type === "string" && (required.has(name) || hasDefault(property) || touched.has(control))) {
404
- if (property.format === "date-time") {
405
- const value = dateTimeLocalToRfc3339(control.value);
406
- if (value !== void 0) content[name] = value;
407
- } else {
408
- content[name] = property.type === "number" || property.type === "integer" ? Number(control.value) : control.value;
409
- }
410
- }
411
- }
412
- return content;
413
- }
414
- function updateControlValidity(control, property, required, touched) {
415
- control.setCustomValidity("");
416
- if (!(control instanceof HTMLSelectElement)) return;
417
- if (!control.multiple) {
418
- control.required = required;
419
- if (required && isPlaceholderSelected(control)) {
420
- control.setCustomValidity("Please select an option.");
421
- }
422
- return;
423
- }
424
- const count = control.selectedOptions.length;
425
- const included = shouldIncludeArray(property, required, touched, count);
426
- const minimum = integerBound(property.minItems);
427
- const maximum = integerBound(property.maxItems);
428
- control.required = included && minimum !== void 0 && minimum > 0;
429
- if (included && minimum !== void 0 && count < minimum) {
430
- control.setCustomValidity(`Select at least ${minimum} option${minimum === 1 ? "" : "s"}.`);
431
- } else if (included && maximum !== void 0 && count > maximum) {
432
- control.setCustomValidity(`Select at most ${maximum} option${maximum === 1 ? "" : "s"}.`);
433
- }
434
- }
435
- function shouldIncludeArray(property, required, touched, selectedCount) {
436
- return required || hasDefault(property) || touched || selectedCount > 0;
437
- }
438
- function hasDefault(property) {
439
- return Object.hasOwn(property, "default");
440
- }
441
- function integerBound(value) {
442
- return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
443
- }
444
- function inputNeedsNonEmptyValue(property) {
445
- if (property.type === "number" || property.type === "integer") return true;
446
- if (property.type !== "string") return false;
447
- return property.format === "date" || property.format === "date-time" || property.format === "email" || property.format === "uri" || typeof property.minLength === "number" && property.minLength > 0;
448
- }
449
- function isPlaceholderSelected(select) {
450
- return select.selectedOptions[0]?.dataset.placeholder === "true";
451
- }
452
- function stringChoices(property) {
453
- if (Array.isArray(property.enum) && property.enum.every((value) => typeof value === "string")) {
454
- return property.enum.map((value) => ({ value, title: value }));
455
- }
456
- return titledChoices(property.oneOf) ?? titledChoices(property.anyOf);
457
- }
458
- function arrayChoices(property) {
459
- return stringChoices(record(property.items)) ?? [];
460
- }
461
- function inputType(property) {
462
- if (property.type === "boolean") return "checkbox";
463
- if (property.type === "number" || property.type === "integer") return "number";
464
- if (property.format === "date") return "date";
465
- if (property.format === "date-time") return "datetime-local";
466
- if (property.format === "email") return "email";
467
- if (property.format === "uri") return "url";
468
- return "text";
469
- }
470
- function titledChoices(value) {
471
- if (!Array.isArray(value)) return void 0;
472
- const choices = value.map((item) => record(item));
473
- if (!choices.every((item) => typeof item.const === "string")) return void 0;
474
- return choices.map((item) => ({
475
- value: String(item.const),
476
- title: typeof item.title === "string" ? item.title : String(item.const)
477
- }));
478
- }
479
- function applySelectDefault(select, value) {
480
- if (select.multiple) {
481
- const selected = new Set(
482
- Array.isArray(value) ? value.filter((item) => typeof item === "string") : []
483
- );
484
- for (const item of select.options) item.selected = selected.has(item.value);
485
- return;
486
- }
487
- if (typeof value === "string") select.value = value;
488
- }
489
- function applyInputDefault(input, property) {
490
- const value = property.default;
491
- if (property.type === "boolean") {
492
- if (typeof value === "boolean") input.checked = value;
493
- return;
494
- }
495
- if (property.type === "number" || property.type === "integer") {
496
- if (typeof value === "number" && Number.isFinite(value)) input.value = String(value);
497
- return;
498
- }
499
- if (typeof value !== "string") return;
500
- if (property.format === "date-time") {
501
- input.value = rfc3339ToDateTimeLocal(value) ?? "";
502
- return;
503
- }
504
- input.value = value;
505
- }
506
- function rfc3339ToDateTimeLocal(value) {
507
- const instant = new Date(value);
508
- if (Number.isNaN(instant.valueOf())) return void 0;
509
- return [
510
- String(instant.getFullYear()).padStart(4, "0"),
511
- "-",
512
- twoDigits(instant.getMonth() + 1),
513
- "-",
514
- twoDigits(instant.getDate()),
515
- "T",
516
- twoDigits(instant.getHours()),
517
- ":",
518
- twoDigits(instant.getMinutes()),
519
- ":",
520
- twoDigits(instant.getSeconds()),
521
- ".",
522
- String(instant.getMilliseconds()).padStart(3, "0")
523
- ].join("");
524
- }
525
- function dateTimeLocalToRfc3339(value) {
526
- const instant = new Date(value);
527
- return Number.isNaN(instant.valueOf()) ? void 0 : instant.toISOString();
528
- }
529
- function twoDigits(value) {
530
- return String(value).padStart(2, "0");
531
- }
532
- function button(label, type) {
533
- const element = document.createElement("button");
534
- element.type = type;
535
- element.textContent = label;
536
- return element;
537
- }
538
- function option(label, value) {
539
- const element = document.createElement("option");
540
- element.textContent = label;
541
- element.value = value;
542
- return element;
543
- }
544
- function placeholderOption(choices) {
545
- let value = "";
546
- while (choices.some((choice) => choice.value === value)) value += "\0";
547
- const element = option("", value);
548
- element.dataset.placeholder = "true";
549
- return element;
550
- }
551
- function humanize(value) {
552
- const words = value.replaceAll(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll(/[_-]+/g, " ");
553
- return words ? `${words[0]?.toUpperCase() ?? ""}${words.slice(1)}` : value;
554
- }
555
- function record(value) {
556
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
557
- }
558
-
559
- // src/interaction-card.ts
560
- function createInteractionCard(options) {
561
- const card = document.createElement("section");
562
- card.className = "tool-proposal";
563
- const label = document.createElement("strong");
564
- label.textContent = options.tool;
565
- card.append(label);
566
- if (options.arguments && Object.keys(options.arguments).length > 0) {
567
- card.append(createArgumentList(options.arguments));
568
- }
569
- const actions = document.createElement("div");
570
- actions.className = "proposal-actions";
571
- const buttons = [];
572
- for (const [labelText, action] of [
573
- [options.labels.accept, "accept"],
574
- [options.labels.decline, "decline"],
575
- [options.labels.cancel, "cancel"]
576
- ]) {
577
- const button2 = document.createElement("button");
578
- button2.type = "button";
579
- button2.textContent = labelText;
580
- buttons.push(button2);
581
- button2.addEventListener("click", () => {
582
- for (const candidate of buttons) candidate.disabled = true;
583
- void options.respond(action).catch(() => {
584
- for (const candidate of buttons) candidate.disabled = false;
585
- });
586
- });
587
- actions.append(button2);
588
- }
589
- card.append(actions);
590
- return card;
591
- }
592
- function createArgumentList(arguments_) {
593
- const details = document.createElement("dl");
594
- details.className = "proposal-arguments";
595
- for (const [name, value] of Object.entries(arguments_)) {
596
- const term = document.createElement("dt");
597
- term.textContent = humanizeArgumentName(name);
598
- const description = document.createElement("dd");
599
- description.textContent = formatArgumentValue(value);
600
- details.append(term, description);
601
- }
602
- return details;
603
- }
604
- function humanizeArgumentName(value) {
605
- const words = value.replaceAll(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll(/[_-]+/g, " ");
606
- return words ? `${words[0]?.toUpperCase() ?? ""}${words.slice(1)}` : value;
607
- }
608
- function formatArgumentValue(value) {
609
- if (value === null) return "None";
610
- if (typeof value === "string") return value;
611
- if (typeof value === "number" || typeof value === "boolean") return String(value);
612
- return JSON.stringify(value) ?? "";
613
- }
614
-
615
- // ../../node_modules/.pnpm/dompurify@3.4.11/node_modules/dompurify/dist/purify.es.mjs
616
- function _arrayLikeToArray(r, a) {
617
- (null == a || a > r.length) && (a = r.length);
618
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
619
- return n;
620
- }
621
- function _arrayWithHoles(r) {
622
- if (Array.isArray(r)) return r;
623
- }
624
- function _iterableToArrayLimit(r, l3) {
625
- var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
626
- if (null != t) {
627
- var e, n, i, u, a = [], f = true, o = false;
628
- try {
629
- if (i = (t = t.call(r)).next, 0 === l3) ;
630
- else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l3); f = true) ;
631
- } catch (r2) {
632
- o = true, n = r2;
633
- } finally {
634
- try {
635
- if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
636
- } finally {
637
- if (o) throw n;
638
- }
639
- }
640
- return a;
641
- }
642
- }
643
- function _nonIterableRest() {
644
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
645
- }
646
- function _slicedToArray(r, e) {
647
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
648
- }
649
- function _unsupportedIterableToArray(r, a) {
650
- if (r) {
651
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
652
- var t = {}.toString.call(r).slice(8, -1);
653
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
654
- }
655
- }
656
- var entries = Object.entries;
657
- var setPrototypeOf = Object.setPrototypeOf;
658
- var isFrozen = Object.isFrozen;
659
- var getPrototypeOf = Object.getPrototypeOf;
660
- var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
661
- var freeze = Object.freeze;
662
- var seal = Object.seal;
663
- var create = Object.create;
664
- var _ref = typeof Reflect !== "undefined" && Reflect;
665
- var apply = _ref.apply;
666
- var construct = _ref.construct;
667
- if (!freeze) {
668
- freeze = function freeze2(x2) {
669
- return x2;
670
- };
671
- }
672
- if (!seal) {
673
- seal = function seal2(x2) {
674
- return x2;
675
- };
676
- }
677
- if (!apply) {
678
- apply = function apply2(func, thisArg) {
679
- for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
680
- args[_key - 2] = arguments[_key];
681
- }
682
- return func.apply(thisArg, args);
683
- };
684
- }
685
- if (!construct) {
686
- construct = function construct2(Func) {
687
- for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
688
- args[_key2 - 1] = arguments[_key2];
689
- }
690
- return new Func(...args);
691
- };
692
- }
693
- var arrayForEach = unapply(Array.prototype.forEach);
694
- var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
695
- var arrayPop = unapply(Array.prototype.pop);
696
- var arrayPush = unapply(Array.prototype.push);
697
- var arraySplice = unapply(Array.prototype.splice);
698
- var arrayIsArray = Array.isArray;
699
- var stringToLowerCase = unapply(String.prototype.toLowerCase);
700
- var stringToString = unapply(String.prototype.toString);
701
- var stringMatch = unapply(String.prototype.match);
702
- var stringReplace = unapply(String.prototype.replace);
703
- var stringIndexOf = unapply(String.prototype.indexOf);
704
- var stringTrim = unapply(String.prototype.trim);
705
- var numberToString = unapply(Number.prototype.toString);
706
- var booleanToString = unapply(Boolean.prototype.toString);
707
- var bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
708
- var symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
709
- var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
710
- var objectToString = unapply(Object.prototype.toString);
711
- var regExpTest = unapply(RegExp.prototype.test);
712
- var typeErrorCreate = unconstruct(TypeError);
713
- function unapply(func) {
714
- return function(thisArg) {
715
- if (thisArg instanceof RegExp) {
716
- thisArg.lastIndex = 0;
717
- }
718
- for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
719
- args[_key3 - 1] = arguments[_key3];
720
- }
721
- return apply(func, thisArg, args);
722
- };
723
- }
724
- function unconstruct(Func) {
725
- return function() {
726
- for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
727
- args[_key4] = arguments[_key4];
728
- }
729
- return construct(Func, args);
730
- };
731
- }
732
- function addToSet(set, array) {
733
- let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
734
- if (setPrototypeOf) {
735
- setPrototypeOf(set, null);
736
- }
737
- if (!arrayIsArray(array)) {
738
- return set;
739
- }
740
- let l3 = array.length;
741
- while (l3--) {
742
- let element = array[l3];
743
- if (typeof element === "string") {
744
- const lcElement = transformCaseFunc(element);
745
- if (lcElement !== element) {
746
- if (!isFrozen(array)) {
747
- array[l3] = lcElement;
748
- }
749
- element = lcElement;
750
- }
751
- }
752
- set[element] = true;
753
- }
754
- return set;
755
- }
756
- function cleanArray(array) {
757
- for (let index = 0; index < array.length; index++) {
758
- const isPropertyExist = objectHasOwnProperty(array, index);
759
- if (!isPropertyExist) {
760
- array[index] = null;
761
- }
762
- }
763
- return array;
764
- }
765
- function clone(object) {
766
- const newObject = create(null);
767
- for (const _ref2 of entries(object)) {
768
- var _ref3 = _slicedToArray(_ref2, 2);
769
- const property = _ref3[0];
770
- const value = _ref3[1];
771
- const isPropertyExist = objectHasOwnProperty(object, property);
772
- if (isPropertyExist) {
773
- if (arrayIsArray(value)) {
774
- newObject[property] = cleanArray(value);
775
- } else if (value && typeof value === "object" && value.constructor === Object) {
776
- newObject[property] = clone(value);
777
- } else {
778
- newObject[property] = value;
779
- }
780
- }
781
- }
782
- return newObject;
783
- }
784
- function stringifyValue(value) {
785
- switch (typeof value) {
786
- case "string": {
787
- return value;
788
- }
789
- case "number": {
790
- return numberToString(value);
791
- }
792
- case "boolean": {
793
- return booleanToString(value);
794
- }
795
- case "bigint": {
796
- return bigintToString ? bigintToString(value) : "0";
797
- }
798
- case "symbol": {
799
- return symbolToString ? symbolToString(value) : "Symbol()";
800
- }
801
- case "undefined": {
802
- return objectToString(value);
803
- }
804
- case "function":
805
- case "object": {
806
- if (value === null) {
807
- return objectToString(value);
808
- }
809
- const valueAsRecord = value;
810
- const valueToString = lookupGetter(valueAsRecord, "toString");
811
- if (typeof valueToString === "function") {
812
- const stringified = valueToString(valueAsRecord);
813
- return typeof stringified === "string" ? stringified : objectToString(stringified);
814
- }
815
- return objectToString(value);
816
- }
817
- default: {
818
- return objectToString(value);
819
- }
820
- }
821
- }
822
- function lookupGetter(object, prop) {
823
- while (object !== null) {
824
- const desc = getOwnPropertyDescriptor(object, prop);
825
- if (desc) {
826
- if (desc.get) {
827
- return unapply(desc.get);
828
- }
829
- if (typeof desc.value === "function") {
830
- return unapply(desc.value);
831
- }
832
- }
833
- object = getPrototypeOf(object);
834
- }
835
- function fallbackValue() {
836
- return null;
837
- }
838
- return fallbackValue;
839
- }
840
- function isRegex(value) {
841
- try {
842
- regExpTest(value, "");
843
- return true;
844
- } catch (_unused) {
845
- return false;
846
- }
847
- }
848
- var html$1 = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "search", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]);
849
- var svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "enterkeyhint", "exportparts", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "inputmode", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "part", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]);
850
- var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence"]);
851
- var svgDisallowed = freeze(["animate", "color-profile", "cursor", "discard", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignobject", "hatch", "hatchpath", "mesh", "meshgradient", "meshpatch", "meshrow", "missing-glyph", "script", "set", "solidcolor", "unknown", "use"]);
852
- var mathMl$1 = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "mprescripts"]);
853
- var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
854
- var text = freeze(["#text"]);
855
- var html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "command", "commandfor", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "exportparts", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inert", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "part", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "slot", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns"]);
856
- var svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "mask-type", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]);
857
- var mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnalign", "columnlines", "columnspacing", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lquote", "lspace", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]);
858
- var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
859
- var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
860
- var ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
861
- var TMPLIT_EXPR = seal(/\${[\w\W]*/g);
862
- var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
863
- var ARIA_ATTR = seal(/^aria-[\-\w]+$/);
864
- var IS_ALLOWED_URI = seal(
865
- /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
866
- // eslint-disable-line no-useless-escape
867
- );
868
- var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
869
- var ATTR_WHITESPACE = seal(
870
- /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
871
- // eslint-disable-line no-control-regex
872
- );
873
- var DOCTYPE_NAME = seal(/^html$/i);
874
- var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
875
- var ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
876
- var COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
877
- var FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
878
- var SELF_CLOSING_TAG = seal(/\/>/i);
879
- var NODE_TYPE = {
880
- element: 1,
881
- attribute: 2,
882
- text: 3,
883
- cdataSection: 4,
884
- entityReference: 5,
885
- // Deprecated
886
- entityNode: 6,
887
- // Deprecated
888
- processingInstruction: 7,
889
- comment: 8,
890
- document: 9,
891
- documentType: 10,
892
- documentFragment: 11,
893
- notation: 12
894
- // Deprecated
895
- };
896
- var getGlobal = function getGlobal2() {
897
- return typeof window === "undefined" ? null : window;
898
- };
899
- var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) {
900
- if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") {
901
- return null;
902
- }
903
- let suffix = null;
904
- const ATTR_NAME = "data-tt-policy-suffix";
905
- if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
906
- suffix = purifyHostElement.getAttribute(ATTR_NAME);
907
- }
908
- const policyName = "dompurify" + (suffix ? "#" + suffix : "");
909
- try {
910
- return trustedTypes.createPolicy(policyName, {
911
- createHTML(html2) {
912
- return html2;
913
- },
914
- createScriptURL(scriptUrl) {
915
- return scriptUrl;
916
- }
917
- });
918
- } catch (_2) {
919
- console.warn("TrustedTypes policy " + policyName + " could not be created.");
920
- return null;
921
- }
922
- };
923
- var _createHooksMap = function _createHooksMap2() {
924
- return {
925
- afterSanitizeAttributes: [],
926
- afterSanitizeElements: [],
927
- afterSanitizeShadowDOM: [],
928
- beforeSanitizeAttributes: [],
929
- beforeSanitizeElements: [],
930
- beforeSanitizeShadowDOM: [],
931
- uponSanitizeAttribute: [],
932
- uponSanitizeElement: [],
933
- uponSanitizeShadowNode: []
934
- };
935
- };
936
- var _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
937
- return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
938
- };
939
- function createDOMPurify() {
940
- let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
941
- const DOMPurify = (root) => createDOMPurify(root);
942
- DOMPurify.version = "3.4.11";
943
- DOMPurify.removed = [];
944
- if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
945
- DOMPurify.isSupported = false;
946
- return DOMPurify;
947
- }
948
- let document2 = window2.document;
949
- const originalDocument = document2;
950
- const currentScript = originalDocument.currentScript;
951
- window2.DocumentFragment;
952
- const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
953
- _window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
954
- window2.HTMLFormElement;
955
- const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
956
- const ElementPrototype = Element.prototype;
957
- const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
958
- const remove = lookupGetter(ElementPrototype, "remove");
959
- const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
960
- const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
961
- const getParentNode = lookupGetter(ElementPrototype, "parentNode");
962
- const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
963
- const getAttributes = lookupGetter(ElementPrototype, "attributes");
964
- const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
965
- const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
966
- if (typeof HTMLTemplateElement === "function") {
967
- const template = document2.createElement("template");
968
- if (template.content && template.content.ownerDocument) {
969
- document2 = template.content.ownerDocument;
970
- }
971
- }
972
- let trustedTypesPolicy;
973
- let emptyHTML = "";
974
- let defaultTrustedTypesPolicy;
975
- let defaultTrustedTypesPolicyResolved = false;
976
- let IN_TRUSTED_TYPES_POLICY = 0;
977
- const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy2() {
978
- if (IN_TRUSTED_TYPES_POLICY > 0) {
979
- throw typeErrorCreate('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.');
980
- }
981
- };
982
- const _createTrustedHTML = function _createTrustedHTML2(html2) {
983
- _assertNotInTrustedTypesPolicy();
984
- IN_TRUSTED_TYPES_POLICY++;
985
- try {
986
- return trustedTypesPolicy.createHTML(html2);
987
- } finally {
988
- IN_TRUSTED_TYPES_POLICY--;
989
- }
990
- };
991
- const _createTrustedScriptURL = function _createTrustedScriptURL2(scriptUrl) {
992
- _assertNotInTrustedTypesPolicy();
993
- IN_TRUSTED_TYPES_POLICY++;
994
- try {
995
- return trustedTypesPolicy.createScriptURL(scriptUrl);
996
- } finally {
997
- IN_TRUSTED_TYPES_POLICY--;
998
- }
999
- };
1000
- const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy2() {
1001
- if (!defaultTrustedTypesPolicyResolved) {
1002
- defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
1003
- defaultTrustedTypesPolicyResolved = true;
1004
- }
1005
- return defaultTrustedTypesPolicy;
1006
- };
1007
- const _document = document2, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
1008
- const importNode = originalDocument.importNode;
1009
- let hooks = _createHooksMap();
1010
- DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
1011
- const MUSTACHE_EXPR$1 = MUSTACHE_EXPR, ERB_EXPR$1 = ERB_EXPR, TMPLIT_EXPR$1 = TMPLIT_EXPR, DATA_ATTR$1 = DATA_ATTR, ARIA_ATTR$1 = ARIA_ATTR, IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA, ATTR_WHITESPACE$1 = ATTR_WHITESPACE, CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
1012
- let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
1013
- let ALLOWED_TAGS = null;
1014
- const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
1015
- let ALLOWED_ATTR = null;
1016
- const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
1017
- let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
1018
- tagNameCheck: {
1019
- writable: true,
1020
- configurable: false,
1021
- enumerable: true,
1022
- value: null
1023
- },
1024
- attributeNameCheck: {
1025
- writable: true,
1026
- configurable: false,
1027
- enumerable: true,
1028
- value: null
1029
- },
1030
- allowCustomizedBuiltInElements: {
1031
- writable: true,
1032
- configurable: false,
1033
- enumerable: true,
1034
- value: false
1035
- }
1036
- }));
1037
- let FORBID_TAGS = null;
1038
- let FORBID_ATTR = null;
1039
- const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
1040
- tagCheck: {
1041
- writable: true,
1042
- configurable: false,
1043
- enumerable: true,
1044
- value: null
1045
- },
1046
- attributeCheck: {
1047
- writable: true,
1048
- configurable: false,
1049
- enumerable: true,
1050
- value: null
1051
- }
1052
- }));
1053
- let ALLOW_ARIA_ATTR = true;
1054
- let ALLOW_DATA_ATTR = true;
1055
- let ALLOW_UNKNOWN_PROTOCOLS = false;
1056
- let ALLOW_SELF_CLOSE_IN_ATTR = true;
1057
- let SAFE_FOR_TEMPLATES = false;
1058
- let SAFE_FOR_XML = true;
1059
- let WHOLE_DOCUMENT = false;
1060
- let SET_CONFIG = false;
1061
- let SET_CONFIG_ALLOWED_TAGS = null;
1062
- let SET_CONFIG_ALLOWED_ATTR = null;
1063
- let FORCE_BODY = false;
1064
- let RETURN_DOM = false;
1065
- let RETURN_DOM_FRAGMENT = false;
1066
- let RETURN_TRUSTED_TYPE = false;
1067
- let SANITIZE_DOM = true;
1068
- let SANITIZE_NAMED_PROPS = false;
1069
- const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
1070
- let KEEP_CONTENT = true;
1071
- let IN_PLACE = false;
1072
- let USE_PROFILES = {};
1073
- let FORBID_CONTENTS = null;
1074
- const DEFAULT_FORBID_CONTENTS = addToSet({}, [
1075
- "annotation-xml",
1076
- "audio",
1077
- "colgroup",
1078
- "desc",
1079
- "foreignobject",
1080
- "head",
1081
- "iframe",
1082
- "math",
1083
- "mi",
1084
- "mn",
1085
- "mo",
1086
- "ms",
1087
- "mtext",
1088
- "noembed",
1089
- "noframes",
1090
- "noscript",
1091
- "plaintext",
1092
- "script",
1093
- // <selectedcontent> mirrors the selected <option>'s subtree, cloned by
1094
- // the UA (customizable <select>) — including any on* handlers — and the
1095
- // engine re-mirrors synchronously whenever a removal changes which
1096
- // option/selectedcontent is current, even inside DOMPurify's inert
1097
- // DOMParser document. Hoisting its children on removal re-inserts a fresh
1098
- // mirror target ahead of the walk, which the engine refills, looping
1099
- // forever (DoS) and amplifying output. Dropping its content on removal
1100
- // (rather than hoisting) breaks that cascade; the content is a duplicate
1101
- // of the option, which is sanitized on its own. See campaign-3 F1/F6.
1102
- "selectedcontent",
1103
- "style",
1104
- "svg",
1105
- "template",
1106
- "thead",
1107
- "title",
1108
- "video",
1109
- "xmp"
1110
- ]);
1111
- let DATA_URI_TAGS = null;
1112
- const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
1113
- let URI_SAFE_ATTRIBUTES = null;
1114
- const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]);
1115
- const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
1116
- const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
1117
- const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
1118
- let NAMESPACE = HTML_NAMESPACE;
1119
- let IS_EMPTY_INPUT = false;
1120
- let ALLOWED_NAMESPACES = null;
1121
- const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
1122
- const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
1123
- let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1124
- const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
1125
- let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1126
- const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
1127
- let PARSER_MEDIA_TYPE = null;
1128
- const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
1129
- const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
1130
- let transformCaseFunc = null;
1131
- let CONFIG = null;
1132
- const formElement = document2.createElement("form");
1133
- const isRegexOrFunction = function isRegexOrFunction2(testValue) {
1134
- return testValue instanceof RegExp || testValue instanceof Function;
1135
- };
1136
- const _parseConfig = function _parseConfig2() {
1137
- let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
1138
- if (CONFIG && CONFIG === cfg) {
1139
- return;
1140
- }
1141
- if (!cfg || typeof cfg !== "object") {
1142
- cfg = {};
1143
- }
1144
- cfg = clone(cfg);
1145
- PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
1146
- SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
1147
- transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
1148
- ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
1149
- transform: transformCaseFunc
1150
- });
1151
- ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
1152
- transform: transformCaseFunc
1153
- });
1154
- ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
1155
- transform: stringToString
1156
- });
1157
- URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
1158
- transform: transformCaseFunc,
1159
- base: DEFAULT_URI_SAFE_ATTRIBUTES
1160
- });
1161
- DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
1162
- transform: transformCaseFunc,
1163
- base: DEFAULT_DATA_URI_TAGS
1164
- });
1165
- FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
1166
- transform: transformCaseFunc
1167
- });
1168
- FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
1169
- transform: transformCaseFunc
1170
- });
1171
- FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
1172
- transform: transformCaseFunc
1173
- });
1174
- USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
1175
- ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
1176
- ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
1177
- ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
1178
- ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
1179
- SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
1180
- SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
1181
- WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
1182
- RETURN_DOM = cfg.RETURN_DOM || false;
1183
- RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
1184
- RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
1185
- FORCE_BODY = cfg.FORCE_BODY || false;
1186
- SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
1187
- SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
1188
- KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
1189
- IN_PLACE = cfg.IN_PLACE || false;
1190
- IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
1191
- NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
1192
- MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1193
- HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1194
- const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
1195
- CUSTOM_ELEMENT_HANDLING = create(null);
1196
- if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
1197
- CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
1198
- }
1199
- if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
1200
- CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
1201
- }
1202
- if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
1203
- CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
1204
- }
1205
- seal(CUSTOM_ELEMENT_HANDLING);
1206
- if (SAFE_FOR_TEMPLATES) {
1207
- ALLOW_DATA_ATTR = false;
1208
- }
1209
- if (RETURN_DOM_FRAGMENT) {
1210
- RETURN_DOM = true;
1211
- }
1212
- if (USE_PROFILES) {
1213
- ALLOWED_TAGS = addToSet({}, text);
1214
- ALLOWED_ATTR = create(null);
1215
- if (USE_PROFILES.html === true) {
1216
- addToSet(ALLOWED_TAGS, html$1);
1217
- addToSet(ALLOWED_ATTR, html);
1218
- }
1219
- if (USE_PROFILES.svg === true) {
1220
- addToSet(ALLOWED_TAGS, svg$1);
1221
- addToSet(ALLOWED_ATTR, svg);
1222
- addToSet(ALLOWED_ATTR, xml);
1223
- }
1224
- if (USE_PROFILES.svgFilters === true) {
1225
- addToSet(ALLOWED_TAGS, svgFilters);
1226
- addToSet(ALLOWED_ATTR, svg);
1227
- addToSet(ALLOWED_ATTR, xml);
1228
- }
1229
- if (USE_PROFILES.mathMl === true) {
1230
- addToSet(ALLOWED_TAGS, mathMl$1);
1231
- addToSet(ALLOWED_ATTR, mathMl);
1232
- addToSet(ALLOWED_ATTR, xml);
1233
- }
1234
- }
1235
- EXTRA_ELEMENT_HANDLING.tagCheck = null;
1236
- EXTRA_ELEMENT_HANDLING.attributeCheck = null;
1237
- if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
1238
- if (typeof cfg.ADD_TAGS === "function") {
1239
- EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
1240
- } else if (arrayIsArray(cfg.ADD_TAGS)) {
1241
- if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
1242
- ALLOWED_TAGS = clone(ALLOWED_TAGS);
1243
- }
1244
- addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
1245
- }
1246
- }
1247
- if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
1248
- if (typeof cfg.ADD_ATTR === "function") {
1249
- EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
1250
- } else if (arrayIsArray(cfg.ADD_ATTR)) {
1251
- if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
1252
- ALLOWED_ATTR = clone(ALLOWED_ATTR);
1253
- }
1254
- addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
1255
- }
1256
- }
1257
- if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
1258
- addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
1259
- }
1260
- if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
1261
- if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
1262
- FORBID_CONTENTS = clone(FORBID_CONTENTS);
1263
- }
1264
- addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
1265
- }
1266
- if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
1267
- if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
1268
- FORBID_CONTENTS = clone(FORBID_CONTENTS);
1269
- }
1270
- addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
1271
- }
1272
- if (KEEP_CONTENT) {
1273
- ALLOWED_TAGS["#text"] = true;
1274
- }
1275
- if (WHOLE_DOCUMENT) {
1276
- addToSet(ALLOWED_TAGS, ["html", "head", "body"]);
1277
- }
1278
- if (ALLOWED_TAGS.table) {
1279
- addToSet(ALLOWED_TAGS, ["tbody"]);
1280
- delete FORBID_TAGS.tbody;
1281
- }
1282
- if (cfg.TRUSTED_TYPES_POLICY) {
1283
- if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") {
1284
- throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
1285
- }
1286
- if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
1287
- throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
1288
- }
1289
- const previousTrustedTypesPolicy = trustedTypesPolicy;
1290
- trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
1291
- try {
1292
- emptyHTML = _createTrustedHTML("");
1293
- } catch (error) {
1294
- trustedTypesPolicy = previousTrustedTypesPolicy;
1295
- throw error;
1296
- }
1297
- } else if (cfg.TRUSTED_TYPES_POLICY === null) {
1298
- trustedTypesPolicy = void 0;
1299
- emptyHTML = "";
1300
- } else {
1301
- if (trustedTypesPolicy === void 0) {
1302
- trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
1303
- }
1304
- if (trustedTypesPolicy && typeof emptyHTML === "string") {
1305
- emptyHTML = _createTrustedHTML("");
1306
- }
1307
- }
1308
- if (freeze) {
1309
- freeze(cfg);
1310
- }
1311
- CONFIG = cfg;
1312
- };
1313
- const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
1314
- const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
1315
- const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
1316
- if (parent.namespaceURI === HTML_NAMESPACE) {
1317
- return tagName === "svg";
1318
- }
1319
- if (parent.namespaceURI === MATHML_NAMESPACE) {
1320
- return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
1321
- }
1322
- return Boolean(ALL_SVG_TAGS[tagName]);
1323
- };
1324
- const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
1325
- if (parent.namespaceURI === HTML_NAMESPACE) {
1326
- return tagName === "math";
1327
- }
1328
- if (parent.namespaceURI === SVG_NAMESPACE) {
1329
- return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
1330
- }
1331
- return Boolean(ALL_MATHML_TAGS[tagName]);
1332
- };
1333
- const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
1334
- if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
1335
- return false;
1336
- }
1337
- if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
1338
- return false;
1339
- }
1340
- return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
1341
- };
1342
- const _checkValidNamespace = function _checkValidNamespace2(element) {
1343
- let parent = getParentNode(element);
1344
- if (!parent || !parent.tagName) {
1345
- parent = {
1346
- namespaceURI: NAMESPACE,
1347
- tagName: "template"
1348
- };
1349
- }
1350
- const tagName = stringToLowerCase(element.tagName);
1351
- const parentTagName = stringToLowerCase(parent.tagName);
1352
- if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
1353
- return false;
1354
- }
1355
- if (element.namespaceURI === SVG_NAMESPACE) {
1356
- return _checkSvgNamespace(tagName, parent, parentTagName);
1357
- }
1358
- if (element.namespaceURI === MATHML_NAMESPACE) {
1359
- return _checkMathMlNamespace(tagName, parent, parentTagName);
1360
- }
1361
- if (element.namespaceURI === HTML_NAMESPACE) {
1362
- return _checkHtmlNamespace(tagName, parent, parentTagName);
1363
- }
1364
- if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
1365
- return true;
1366
- }
1367
- return false;
1368
- };
1369
- const _forceRemove = function _forceRemove2(node) {
1370
- arrayPush(DOMPurify.removed, {
1371
- element: node
1372
- });
1373
- try {
1374
- getParentNode(node).removeChild(node);
1375
- } catch (_2) {
1376
- remove(node);
1377
- if (!getParentNode(node)) {
1378
- throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
1379
- }
1380
- }
1381
- };
1382
- const _neutralizeRoot = function _neutralizeRoot2(root) {
1383
- const childNodes = getChildNodes(root);
1384
- if (childNodes) {
1385
- const snapshot = [];
1386
- arrayForEach(childNodes, (child) => {
1387
- arrayPush(snapshot, child);
1388
- });
1389
- arrayForEach(snapshot, (child) => {
1390
- try {
1391
- remove(child);
1392
- } catch (_2) {
1393
- }
1394
- });
1395
- }
1396
- const attributes = getAttributes(root);
1397
- if (attributes) {
1398
- for (let i = attributes.length - 1; i >= 0; --i) {
1399
- const attribute = attributes[i];
1400
- const name = attribute && attribute.name;
1401
- if (typeof name === "string") {
1402
- try {
1403
- root.removeAttribute(name);
1404
- } catch (_2) {
1405
- }
1406
- }
1407
- }
1408
- }
1409
- };
1410
- const _removeAttribute = function _removeAttribute2(name, element) {
1411
- try {
1412
- arrayPush(DOMPurify.removed, {
1413
- attribute: element.getAttributeNode(name),
1414
- from: element
1415
- });
1416
- } catch (_2) {
1417
- arrayPush(DOMPurify.removed, {
1418
- attribute: null,
1419
- from: element
1420
- });
1421
- }
1422
- element.removeAttribute(name);
1423
- if (name === "is") {
1424
- if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
1425
- try {
1426
- _forceRemove(element);
1427
- } catch (_2) {
1428
- }
1429
- } else {
1430
- try {
1431
- element.setAttribute(name, "");
1432
- } catch (_2) {
1433
- }
1434
- }
1435
- }
1436
- };
1437
- const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
1438
- const attributes = getAttributes(element);
1439
- if (!attributes) {
1440
- return;
1441
- }
1442
- for (let i = attributes.length - 1; i >= 0; --i) {
1443
- const attribute = attributes[i];
1444
- const name = attribute && attribute.name;
1445
- if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) {
1446
- continue;
1447
- }
1448
- try {
1449
- element.removeAttribute(name);
1450
- } catch (_2) {
1451
- }
1452
- }
1453
- };
1454
- const _neutralizeSubtree = function _neutralizeSubtree2(root) {
1455
- const stack = [root];
1456
- while (stack.length > 0) {
1457
- const node = stack.pop();
1458
- const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
1459
- if (nodeType === NODE_TYPE.element) {
1460
- _stripDisallowedAttributes(node);
1461
- }
1462
- const childNodes = getChildNodes(node);
1463
- if (childNodes) {
1464
- for (let i = childNodes.length - 1; i >= 0; --i) {
1465
- stack.push(childNodes[i]);
1466
- }
1467
- }
1468
- }
1469
- };
1470
- const _initDocument = function _initDocument2(dirty) {
1471
- let doc = null;
1472
- let leadingWhitespace = null;
1473
- if (FORCE_BODY) {
1474
- dirty = "<remove></remove>" + dirty;
1475
- } else {
1476
- const matches = stringMatch(dirty, /^[\r\n\t ]+/);
1477
- leadingWhitespace = matches && matches[0];
1478
- }
1479
- if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
1480
- dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
1481
- }
1482
- const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
1483
- if (NAMESPACE === HTML_NAMESPACE) {
1484
- try {
1485
- doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
1486
- } catch (_2) {
1487
- }
1488
- }
1489
- if (!doc || !doc.documentElement) {
1490
- doc = implementation.createDocument(NAMESPACE, "template", null);
1491
- try {
1492
- doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
1493
- } catch (_2) {
1494
- }
1495
- }
1496
- const body = doc.body || doc.documentElement;
1497
- if (dirty && leadingWhitespace) {
1498
- body.insertBefore(document2.createTextNode(leadingWhitespace), body.childNodes[0] || null);
1499
- }
1500
- if (NAMESPACE === HTML_NAMESPACE) {
1501
- return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
1502
- }
1503
- return WHOLE_DOCUMENT ? doc.documentElement : body;
1504
- };
1505
- const _createNodeIterator = function _createNodeIterator2(root) {
1506
- return createNodeIterator.call(
1507
- root.ownerDocument || root,
1508
- root,
1509
- // eslint-disable-next-line no-bitwise
1510
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION,
1511
- null
1512
- );
1513
- };
1514
- const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
1515
- value = stringReplace(value, MUSTACHE_EXPR$1, " ");
1516
- value = stringReplace(value, ERB_EXPR$1, " ");
1517
- value = stringReplace(value, TMPLIT_EXPR$1, " ");
1518
- return value;
1519
- };
1520
- const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
1521
- var _node$querySelectorAl;
1522
- node.normalize();
1523
- const walker = createNodeIterator.call(
1524
- node.ownerDocument || node,
1525
- node,
1526
- // eslint-disable-next-line no-bitwise
1527
- NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION,
1528
- null
1529
- );
1530
- let currentNode = walker.nextNode();
1531
- while (currentNode) {
1532
- currentNode.data = _stripTemplateExpressions(currentNode.data);
1533
- currentNode = walker.nextNode();
1534
- }
1535
- const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
1536
- if (templates) {
1537
- arrayForEach(templates, (tmpl) => {
1538
- if (_isDocumentFragment(tmpl.content)) {
1539
- _scrubTemplateExpressions2(tmpl.content);
1540
- }
1541
- });
1542
- }
1543
- };
1544
- const _isClobbered = function _isClobbered2(element) {
1545
- const realTagName = getNodeName ? getNodeName(element) : null;
1546
- if (typeof realTagName !== "string") {
1547
- return false;
1548
- }
1549
- if (transformCaseFunc(realTagName) !== "form") {
1550
- return false;
1551
- }
1552
- return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || // Realm-safe NamedNodeMap detection: equality against the cached
1553
- // prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
1554
- // makes the direct read diverge from the cached read; a clean form
1555
- // (same-realm OR foreign-realm) has both reads pointing at the same
1556
- // canonical NamedNodeMap.
1557
- element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
1558
- // returns the integer 1 for any Element regardless of realm; direct
1559
- // read on a clobbered form (e.g. <input name="nodeType">) returns
1560
- // the named child element. Cheap addition — nodeType is read from
1561
- // an internal slot, no serialization cost — and removes a residual
1562
- // clobbering surface used by several mXSS / PI / comment branches
1563
- // in _sanitizeElements that compare currentNode.nodeType directly.
1564
- element.nodeType !== getNodeType(element) || // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
1565
- // "childNodes" shadows the prototype getter. Direct reads of
1566
- // form.childNodes from a clobbered form return the named child
1567
- // instead of the real NodeList, so any walk that reads it directly
1568
- // skips the form's real children. Compare the direct read to the
1569
- // cached Node.prototype getter — when the form's named-property
1570
- // getter intercepts the read, the two values differ and we flag
1571
- // the form. This catches every clobbering child type (input,
1572
- // select, etc.) regardless of whether the named child happens to
1573
- // carry a numeric .length, which a typeof-based probe would miss
1574
- // (e.g. HTMLSelectElement.length is a defined unsigned-long).
1575
- element.childNodes !== getChildNodes(element);
1576
- };
1577
- const _isDocumentFragment = function _isDocumentFragment2(value) {
1578
- if (!getNodeType || typeof value !== "object" || value === null) {
1579
- return false;
1580
- }
1581
- try {
1582
- return getNodeType(value) === NODE_TYPE.documentFragment;
1583
- } catch (_2) {
1584
- return false;
1585
- }
1586
- };
1587
- const _isNode = function _isNode2(value) {
1588
- if (!getNodeType || typeof value !== "object" || value === null) {
1589
- return false;
1590
- }
1591
- try {
1592
- return typeof getNodeType(value) === "number";
1593
- } catch (_2) {
1594
- return false;
1595
- }
1596
- };
1597
- function _executeHooks(hooks2, currentNode, data) {
1598
- if (hooks2.length === 0) {
1599
- return;
1600
- }
1601
- arrayForEach(hooks2, (hook) => {
1602
- hook.call(DOMPurify, currentNode, data, CONFIG);
1603
- });
1604
- }
1605
- const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
1606
- if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
1607
- return true;
1608
- }
1609
- if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
1610
- return true;
1611
- }
1612
- if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
1613
- return true;
1614
- }
1615
- if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
1616
- return true;
1617
- }
1618
- return false;
1619
- };
1620
- const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName) {
1621
- if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1622
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
1623
- return false;
1624
- }
1625
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
1626
- return false;
1627
- }
1628
- }
1629
- if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1630
- const parentNode = getParentNode(currentNode);
1631
- const childNodes = getChildNodes(currentNode);
1632
- if (childNodes && parentNode) {
1633
- const childCount = childNodes.length;
1634
- for (let i = childCount - 1; i >= 0; --i) {
1635
- const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
1636
- parentNode.insertBefore(hoisted, getNextSibling(currentNode));
1637
- }
1638
- }
1639
- }
1640
- _forceRemove(currentNode);
1641
- return true;
1642
- };
1643
- const _sanitizeElements = function _sanitizeElements2(currentNode) {
1644
- _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
1645
- if (_isClobbered(currentNode)) {
1646
- _forceRemove(currentNode);
1647
- return true;
1648
- }
1649
- const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
1650
- _executeHooks(hooks.uponSanitizeElement, currentNode, {
1651
- tagName,
1652
- allowedTags: ALLOWED_TAGS
1653
- });
1654
- if (_isUnsafeNode(currentNode, tagName)) {
1655
- _forceRemove(currentNode);
1656
- return true;
1657
- }
1658
- if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
1659
- return _sanitizeDisallowedNode(currentNode, tagName);
1660
- }
1661
- const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
1662
- if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
1663
- _forceRemove(currentNode);
1664
- return true;
1665
- }
1666
- if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
1667
- _forceRemove(currentNode);
1668
- return true;
1669
- }
1670
- if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1671
- const content = _stripTemplateExpressions(currentNode.textContent);
1672
- if (currentNode.textContent !== content) {
1673
- arrayPush(DOMPurify.removed, {
1674
- element: currentNode.cloneNode()
1675
- });
1676
- currentNode.textContent = content;
1677
- }
1678
- }
1679
- _executeHooks(hooks.afterSanitizeElements, currentNode, null);
1680
- return false;
1681
- };
1682
- const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) {
1683
- if (FORBID_ATTR[lcName]) {
1684
- return false;
1685
- }
1686
- if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
1687
- return false;
1688
- }
1689
- const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
1690
- if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ;
1691
- else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
1692
- else if (!nameIsPermitted) {
1693
- if (
1694
- // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1695
- // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1696
- // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
1697
- _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || // Alternative, second condition checks if it's an `is`-attribute, AND
1698
- // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1699
- lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))
1700
- ) ;
1701
- else {
1702
- return false;
1703
- }
1704
- } else if (URI_SAFE_ATTRIBUTES[lcName]) ;
1705
- else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
1706
- else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) ;
1707
- else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
1708
- else if (value) {
1709
- return false;
1710
- } else ;
1711
- return true;
1712
- };
1713
- const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, ["annotation-xml", "color-profile", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "missing-glyph"]);
1714
- const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
1715
- return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
1716
- };
1717
- const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
1718
- if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
1719
- switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1720
- case "TrustedHTML": {
1721
- return _createTrustedHTML(value);
1722
- }
1723
- case "TrustedScriptURL": {
1724
- return _createTrustedScriptURL(value);
1725
- }
1726
- }
1727
- }
1728
- return value;
1729
- };
1730
- const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
1731
- try {
1732
- if (namespaceURI) {
1733
- currentNode.setAttributeNS(namespaceURI, name, value);
1734
- } else {
1735
- currentNode.setAttribute(name, value);
1736
- }
1737
- if (_isClobbered(currentNode)) {
1738
- _forceRemove(currentNode);
1739
- } else {
1740
- arrayPop(DOMPurify.removed);
1741
- }
1742
- } catch (_2) {
1743
- _removeAttribute(name, currentNode);
1744
- }
1745
- };
1746
- const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
1747
- _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
1748
- const attributes = currentNode.attributes;
1749
- if (!attributes || _isClobbered(currentNode)) {
1750
- return;
1751
- }
1752
- const hookEvent = {
1753
- attrName: "",
1754
- attrValue: "",
1755
- keepAttr: true,
1756
- allowedAttributes: ALLOWED_ATTR,
1757
- forceKeepAttr: void 0
1758
- };
1759
- let l3 = attributes.length;
1760
- const lcTag = transformCaseFunc(currentNode.nodeName);
1761
- while (l3--) {
1762
- const attr = attributes[l3];
1763
- const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
1764
- const lcName = transformCaseFunc(name);
1765
- const initValue = attrValue;
1766
- let value = name === "value" ? initValue : stringTrim(initValue);
1767
- hookEvent.attrName = lcName;
1768
- hookEvent.attrValue = value;
1769
- hookEvent.keepAttr = true;
1770
- hookEvent.forceKeepAttr = void 0;
1771
- _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
1772
- value = hookEvent.attrValue;
1773
- if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
1774
- _removeAttribute(name, currentNode);
1775
- value = SANITIZE_NAMED_PROPS_PREFIX + value;
1776
- }
1777
- if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
1778
- _removeAttribute(name, currentNode);
1779
- continue;
1780
- }
1781
- if (lcName === "attributename" && stringMatch(value, "href")) {
1782
- _removeAttribute(name, currentNode);
1783
- continue;
1784
- }
1785
- if (hookEvent.forceKeepAttr) {
1786
- continue;
1787
- }
1788
- if (!hookEvent.keepAttr) {
1789
- _removeAttribute(name, currentNode);
1790
- continue;
1791
- }
1792
- if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
1793
- _removeAttribute(name, currentNode);
1794
- continue;
1795
- }
1796
- if (SAFE_FOR_TEMPLATES) {
1797
- value = _stripTemplateExpressions(value);
1798
- }
1799
- if (!_isValidAttribute(lcTag, lcName, value)) {
1800
- _removeAttribute(name, currentNode);
1801
- continue;
1802
- }
1803
- value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
1804
- if (value !== initValue) {
1805
- _setAttributeValue(currentNode, name, namespaceURI, value);
1806
- }
1807
- }
1808
- _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
1809
- };
1810
- const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
1811
- let shadowNode = null;
1812
- const shadowIterator = _createNodeIterator(fragment);
1813
- _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
1814
- while (shadowNode = shadowIterator.nextNode()) {
1815
- _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
1816
- _sanitizeElements(shadowNode);
1817
- _sanitizeAttributes(shadowNode);
1818
- if (_isDocumentFragment(shadowNode.content)) {
1819
- _sanitizeShadowDOM2(shadowNode.content);
1820
- }
1821
- const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
1822
- if (shadowNodeType === NODE_TYPE.element) {
1823
- const innerSr = getShadowRoot(shadowNode);
1824
- if (_isDocumentFragment(innerSr)) {
1825
- _sanitizeAttachedShadowRoots(innerSr);
1826
- _sanitizeShadowDOM2(innerSr);
1827
- }
1828
- }
1829
- }
1830
- _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
1831
- };
1832
- const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots2(root) {
1833
- const stack = [{
1834
- node: root,
1835
- shadow: null
1836
- }];
1837
- while (stack.length > 0) {
1838
- const item = stack.pop();
1839
- if (item.shadow) {
1840
- _sanitizeShadowDOM2(item.shadow);
1841
- continue;
1842
- }
1843
- const node = item.node;
1844
- const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
1845
- const isElement = nodeType === NODE_TYPE.element;
1846
- const childNodes = getChildNodes(node);
1847
- if (childNodes) {
1848
- for (let i = childNodes.length - 1; i >= 0; --i) {
1849
- stack.push({
1850
- node: childNodes[i],
1851
- shadow: null
1852
- });
1853
- }
1854
- }
1855
- if (isElement) {
1856
- const rootName = getNodeName ? getNodeName(node) : null;
1857
- if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
1858
- const content = node.content;
1859
- if (_isDocumentFragment(content)) {
1860
- stack.push({
1861
- node: content,
1862
- shadow: null
1863
- });
1864
- }
1865
- }
1866
- }
1867
- if (isElement) {
1868
- const sr = getShadowRoot(node);
1869
- if (_isDocumentFragment(sr)) {
1870
- stack.push({
1871
- node: null,
1872
- shadow: sr
1873
- }, {
1874
- node: sr,
1875
- shadow: null
1876
- });
1877
- }
1878
- }
1879
- }
1880
- };
1881
- DOMPurify.sanitize = function(dirty) {
1882
- let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
1883
- let body = null;
1884
- let importedNode = null;
1885
- let currentNode = null;
1886
- let returnNode = null;
1887
- IS_EMPTY_INPUT = !dirty;
1888
- if (IS_EMPTY_INPUT) {
1889
- dirty = "<!-->";
1890
- }
1891
- if (typeof dirty !== "string" && !_isNode(dirty)) {
1892
- dirty = stringifyValue(dirty);
1893
- if (typeof dirty !== "string") {
1894
- throw typeErrorCreate("dirty is not a string, aborting");
1895
- }
1896
- }
1897
- if (!DOMPurify.isSupported) {
1898
- return dirty;
1899
- }
1900
- if (SET_CONFIG) {
1901
- ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
1902
- ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
1903
- } else {
1904
- _parseConfig(cfg);
1905
- }
1906
- if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
1907
- ALLOWED_TAGS = clone(ALLOWED_TAGS);
1908
- }
1909
- if (hooks.uponSanitizeAttribute.length > 0) {
1910
- ALLOWED_ATTR = clone(ALLOWED_ATTR);
1911
- }
1912
- DOMPurify.removed = [];
1913
- const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
1914
- if (inPlace) {
1915
- const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
1916
- if (typeof nn === "string") {
1917
- const tagName = transformCaseFunc(nn);
1918
- if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1919
- throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
1920
- }
1921
- }
1922
- if (_isClobbered(dirty)) {
1923
- throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
1924
- }
1925
- try {
1926
- _sanitizeAttachedShadowRoots(dirty);
1927
- } catch (error) {
1928
- _neutralizeRoot(dirty);
1929
- throw error;
1930
- }
1931
- } else if (_isNode(dirty)) {
1932
- body = _initDocument("<!---->");
1933
- importedNode = body.ownerDocument.importNode(dirty, true);
1934
- if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
1935
- body = importedNode;
1936
- } else if (importedNode.nodeName === "HTML") {
1937
- body = importedNode;
1938
- } else {
1939
- body.appendChild(importedNode);
1940
- }
1941
- _sanitizeAttachedShadowRoots(importedNode);
1942
- } else {
1943
- if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
1944
- dirty.indexOf("<") === -1) {
1945
- return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
1946
- }
1947
- body = _initDocument(dirty);
1948
- if (!body) {
1949
- return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
1950
- }
1951
- }
1952
- if (body && FORCE_BODY) {
1953
- _forceRemove(body.firstChild);
1954
- }
1955
- const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
1956
- try {
1957
- while (currentNode = nodeIterator.nextNode()) {
1958
- _sanitizeElements(currentNode);
1959
- _sanitizeAttributes(currentNode);
1960
- if (_isDocumentFragment(currentNode.content)) {
1961
- _sanitizeShadowDOM2(currentNode.content);
1962
- }
1963
- }
1964
- } catch (error) {
1965
- if (inPlace) {
1966
- _neutralizeRoot(dirty);
1967
- }
1968
- throw error;
1969
- }
1970
- if (inPlace) {
1971
- arrayForEach(DOMPurify.removed, (entry) => {
1972
- if (entry.element) {
1973
- _neutralizeSubtree(entry.element);
1974
- }
1975
- });
1976
- if (SAFE_FOR_TEMPLATES) {
1977
- _scrubTemplateExpressions2(dirty);
1978
- }
1979
- return dirty;
1980
- }
1981
- if (RETURN_DOM) {
1982
- if (SAFE_FOR_TEMPLATES) {
1983
- _scrubTemplateExpressions2(body);
1984
- }
1985
- if (RETURN_DOM_FRAGMENT) {
1986
- returnNode = createDocumentFragment.call(body.ownerDocument);
1987
- while (body.firstChild) {
1988
- returnNode.appendChild(body.firstChild);
1989
- }
1990
- } else {
1991
- returnNode = body;
1992
- }
1993
- if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
1994
- returnNode = importNode.call(originalDocument, returnNode, true);
1995
- }
1996
- return returnNode;
1997
- }
1998
- let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
1999
- if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
2000
- serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
2001
- }
2002
- if (SAFE_FOR_TEMPLATES) {
2003
- serializedHTML = _stripTemplateExpressions(serializedHTML);
2004
- }
2005
- return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
2006
- };
2007
- DOMPurify.setConfig = function() {
2008
- let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
2009
- _parseConfig(cfg);
2010
- SET_CONFIG = true;
2011
- SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
2012
- SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
2013
- };
2014
- DOMPurify.clearConfig = function() {
2015
- CONFIG = null;
2016
- SET_CONFIG = false;
2017
- SET_CONFIG_ALLOWED_TAGS = null;
2018
- SET_CONFIG_ALLOWED_ATTR = null;
2019
- trustedTypesPolicy = defaultTrustedTypesPolicy;
2020
- emptyHTML = "";
2021
- };
2022
- DOMPurify.isValidAttribute = function(tag, attr, value) {
2023
- if (!CONFIG) {
2024
- _parseConfig({});
2025
- }
2026
- const lcTag = transformCaseFunc(tag);
2027
- const lcName = transformCaseFunc(attr);
2028
- return _isValidAttribute(lcTag, lcName, value);
2029
- };
2030
- DOMPurify.addHook = function(entryPoint, hookFunction) {
2031
- if (typeof hookFunction !== "function") {
2032
- return;
2033
- }
2034
- if (!objectHasOwnProperty(hooks, entryPoint)) {
2035
- return;
2036
- }
2037
- arrayPush(hooks[entryPoint], hookFunction);
2038
- };
2039
- DOMPurify.removeHook = function(entryPoint, hookFunction) {
2040
- if (!objectHasOwnProperty(hooks, entryPoint)) {
2041
- return void 0;
2042
- }
2043
- if (hookFunction !== void 0) {
2044
- const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
2045
- return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
2046
- }
2047
- return arrayPop(hooks[entryPoint]);
2048
- };
2049
- DOMPurify.removeHooks = function(entryPoint) {
2050
- if (!objectHasOwnProperty(hooks, entryPoint)) {
2051
- return;
2052
- }
2053
- hooks[entryPoint] = [];
2054
- };
2055
- DOMPurify.removeAllHooks = function() {
2056
- hooks = _createHooksMap();
2057
- };
2058
- return DOMPurify;
2059
- }
2060
- var purify = createDOMPurify();
2061
-
2062
- // ../../node_modules/.pnpm/marked@16.4.2/node_modules/marked/lib/marked.esm.js
2063
- function L() {
2064
- return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
2065
- }
2066
- var T = L();
2067
- function G(l3) {
2068
- T = l3;
2069
- }
2070
- var E = { exec: () => null };
2071
- function d(l3, e = "") {
2072
- let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (r, i) => {
2073
- let s = typeof i == "string" ? i : i.source;
2074
- return s = s.replace(m.caret, "$1"), t = t.replace(r, s), n;
2075
- }, getRegex: () => new RegExp(t, e) };
2076
- return n;
2077
- }
2078
- var be = (() => {
2079
- try {
2080
- return !!new RegExp("(?<=1)(?<!1)");
2081
- } catch {
2082
- return false;
2083
- }
2084
- })();
2085
- var 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, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] /, listReplaceTask: /^\[[ 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, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}#`), htmlBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}<(?:[a-z].*>|!--)`, "i") };
2086
- var Re = /^(?:[ \t]*(?:\n|$))+/;
2087
- var Te = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
2088
- var Oe = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
2089
- var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
2090
- var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
2091
- var F = /(?:[*+-]|\d{1,9}[.)])/;
2092
- var ie = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
2093
- var oe = d(ie).replace(/bull/g, F).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();
2094
- var ye = d(ie).replace(/bull/g, F).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();
2095
- var j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
2096
- var Pe = /^[^\n]+/;
2097
- var Q = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
2098
- var Se = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Q).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
2099
- var $e = d(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, F).getRegex();
2100
- var 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";
2101
- var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
2102
- var _e = d("^ {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();
2103
- var ae = d(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[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
2104
- var Le = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ae).getRegex();
2105
- var K = { blockquote: Le, code: Te, def: Se, fences: Oe, heading: we, hr: I, html: _e, lheading: oe, list: $e, newline: Re, paragraph: ae, table: E, text: Pe };
2106
- var re = d("^ *([^\\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[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
2107
- var Me = { ...K, lheading: ye, table: re, paragraph: d(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[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
2108
- var ze = { ...K, html: d(`^ *(?: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: E, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: d(j).replace("hr", I).replace("heading", ` *#{1,6} *[^
2109
- ]`).replace("lheading", oe).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
2110
- var Ae = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
2111
- var Ee = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
2112
- var le = /^( {2,}|\\)\n(?!\s*$)/;
2113
- var Ie = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
2114
- var D = /[\p{P}\p{S}]/u;
2115
- var W = /[\s\p{P}\p{S}]/u;
2116
- var ue = /[^\s\p{P}\p{S}]/u;
2117
- var Ce = d(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, W).getRegex();
2118
- var pe = /(?!~)[\p{P}\p{S}]/u;
2119
- var Be = /(?!~)[\s\p{P}\p{S}]/u;
2120
- var qe = /(?:[^\s\p{P}\p{S}]|~)/u;
2121
- var ve = d(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", be ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
2122
- var ce = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
2123
- var De = d(ce, "u").replace(/punct/g, D).getRegex();
2124
- var He = d(ce, "u").replace(/punct/g, pe).getRegex();
2125
- var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
2126
- var Ze = d(he, "gu").replace(/notPunctSpace/g, ue).replace(/punctSpace/g, W).replace(/punct/g, D).getRegex();
2127
- var Ge = d(he, "gu").replace(/notPunctSpace/g, qe).replace(/punctSpace/g, Be).replace(/punct/g, pe).getRegex();
2128
- var Ne = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ue).replace(/punctSpace/g, W).replace(/punct/g, D).getRegex();
2129
- var Fe = d(/\\(punct)/, "gu").replace(/punct/g, D).getRegex();
2130
- var je = d(/^<(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();
2131
- var Qe = d(U).replace("(?:-->|$)", "-->").getRegex();
2132
- var Ue = d("^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", Qe).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
2133
- var q = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/;
2134
- var Ke = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
2135
- var de = d(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", Q).getRegex();
2136
- var ke = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", Q).getRegex();
2137
- var We = d("reflink|nolink(?!\\()", "g").replace("reflink", de).replace("nolink", ke).getRegex();
2138
- var se = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
2139
- var X = { _backpedal: E, anyPunctuation: Fe, autolink: je, blockSkip: ve, br: le, code: Ee, del: E, emStrongLDelim: De, emStrongRDelimAst: Ze, emStrongRDelimUnd: Ne, escape: Ae, link: Ke, nolink: ke, punctuation: Ce, reflink: de, reflinkSearch: We, tag: Ue, text: Ie, url: E };
2140
- var Xe = { ...X, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
2141
- var N = { ...X, emStrongRDelimAst: Ge, emStrongLDelim: He, url: d(/^((?: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: d(/^([`~]+|[^`~])(?:(?= {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() };
2142
- var Je = { ...N, br: d(le).replace("{2,}", "*").getRegex(), text: d(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
2143
- var C = { normal: K, gfm: Me, pedantic: ze };
2144
- var M = { normal: X, gfm: N, breaks: Je, pedantic: Xe };
2145
- var Ve = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
2146
- var ge = (l3) => Ve[l3];
2147
- function w(l3, e) {
2148
- if (e) {
2149
- if (m.escapeTest.test(l3)) return l3.replace(m.escapeReplace, ge);
2150
- } else if (m.escapeTestNoEncode.test(l3)) return l3.replace(m.escapeReplaceNoEncode, ge);
2151
- return l3;
2152
- }
2153
- function J(l3) {
2154
- try {
2155
- l3 = encodeURI(l3).replace(m.percentDecode, "%");
2156
- } catch {
2157
- return null;
2158
- }
2159
- return l3;
2160
- }
2161
- function V(l3, e) {
2162
- let t = l3.replace(m.findPipe, (i, s, a) => {
2163
- let o = false, p = s;
2164
- for (; --p >= 0 && a[p] === "\\"; ) o = !o;
2165
- return o ? "|" : " |";
2166
- }), n = t.split(m.splitPipe), r = 0;
2167
- if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
2168
- else for (; n.length < e; ) n.push("");
2169
- for (; r < n.length; r++) n[r] = n[r].trim().replace(m.slashPipe, "|");
2170
- return n;
2171
- }
2172
- function z(l3, e, t) {
2173
- let n = l3.length;
2174
- if (n === 0) return "";
2175
- let r = 0;
2176
- for (; r < n; ) {
2177
- let i = l3.charAt(n - r - 1);
2178
- if (i === e && !t) r++;
2179
- else if (i !== e && t) r++;
2180
- else break;
2181
- }
2182
- return l3.slice(0, n - r);
2183
- }
2184
- function fe(l3, e) {
2185
- if (l3.indexOf(e[1]) === -1) return -1;
2186
- let t = 0;
2187
- for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++;
2188
- else if (l3[n] === e[0]) t++;
2189
- else if (l3[n] === e[1] && (t--, t < 0)) return n;
2190
- return t > 0 ? -2 : -1;
2191
- }
2192
- function me(l3, e, t, n, r) {
2193
- let i = e.href, s = e.title || null, a = l3[1].replace(r.other.outputLinkReplace, "$1");
2194
- n.state.inLink = true;
2195
- let o = { type: l3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: s, text: a, tokens: n.inlineTokens(a) };
2196
- return n.state.inLink = false, o;
2197
- }
2198
- function Ye(l3, e, t) {
2199
- let n = l3.match(t.other.indentCodeCompensation);
2200
- if (n === null) return e;
2201
- let r = n[1];
2202
- return e.split(`
2203
- `).map((i) => {
2204
- let s = i.match(t.other.beginningSpace);
2205
- if (s === null) return i;
2206
- let [a] = s;
2207
- return a.length >= r.length ? i.slice(r.length) : i;
2208
- }).join(`
2209
- `);
2210
- }
2211
- var y = class {
2212
- options;
2213
- rules;
2214
- lexer;
2215
- constructor(e) {
2216
- this.options = e || T;
2217
- }
2218
- space(e) {
2219
- let t = this.rules.block.newline.exec(e);
2220
- if (t && t[0].length > 0) return { type: "space", raw: t[0] };
2221
- }
2222
- code(e) {
2223
- let t = this.rules.block.code.exec(e);
2224
- if (t) {
2225
- let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
2226
- return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : z(n, `
2227
- `) };
2228
- }
2229
- }
2230
- fences(e) {
2231
- let t = this.rules.block.fences.exec(e);
2232
- if (t) {
2233
- let n = t[0], r = Ye(n, t[3] || "", this.rules);
2234
- return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: r };
2235
- }
2236
- }
2237
- heading(e) {
2238
- let t = this.rules.block.heading.exec(e);
2239
- if (t) {
2240
- let n = t[2].trim();
2241
- if (this.rules.other.endingHash.test(n)) {
2242
- let r = z(n, "#");
2243
- (this.options.pedantic || !r || this.rules.other.endingSpaceChar.test(r)) && (n = r.trim());
2244
- }
2245
- return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
2246
- }
2247
- }
2248
- hr(e) {
2249
- let t = this.rules.block.hr.exec(e);
2250
- if (t) return { type: "hr", raw: z(t[0], `
2251
- `) };
2252
- }
2253
- blockquote(e) {
2254
- let t = this.rules.block.blockquote.exec(e);
2255
- if (t) {
2256
- let n = z(t[0], `
2257
- `).split(`
2258
- `), r = "", i = "", s = [];
2259
- for (; n.length > 0; ) {
2260
- let a = false, o = [], p;
2261
- for (p = 0; p < n.length; p++) if (this.rules.other.blockquoteStart.test(n[p])) o.push(n[p]), a = true;
2262
- else if (!a) o.push(n[p]);
2263
- else break;
2264
- n = n.slice(p);
2265
- let u = o.join(`
2266
- `), c = u.replace(this.rules.other.blockquoteSetextReplace, `
2267
- $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
2268
- r = r ? `${r}
2269
- ${u}` : u, i = i ? `${i}
2270
- ${c}` : c;
2271
- let g = this.lexer.state.top;
2272
- if (this.lexer.state.top = true, this.lexer.blockTokens(c, s, true), this.lexer.state.top = g, n.length === 0) break;
2273
- let h = s.at(-1);
2274
- if (h?.type === "code") break;
2275
- if (h?.type === "blockquote") {
2276
- let R = h, f = R.raw + `
2277
- ` + n.join(`
2278
- `), O = this.blockquote(f);
2279
- s[s.length - 1] = O, r = r.substring(0, r.length - R.raw.length) + O.raw, i = i.substring(0, i.length - R.text.length) + O.text;
2280
- break;
2281
- } else if (h?.type === "list") {
2282
- let R = h, f = R.raw + `
2283
- ` + n.join(`
2284
- `), O = this.list(f);
2285
- s[s.length - 1] = O, r = r.substring(0, r.length - h.raw.length) + O.raw, i = i.substring(0, i.length - R.raw.length) + O.raw, n = f.substring(s.at(-1).raw.length).split(`
2286
- `);
2287
- continue;
2288
- }
2289
- }
2290
- return { type: "blockquote", raw: r, tokens: s, text: i };
2291
- }
2292
- }
2293
- list(e) {
2294
- let t = this.rules.block.list.exec(e);
2295
- if (t) {
2296
- let n = t[1].trim(), r = n.length > 1, i = { type: "list", raw: "", ordered: r, start: r ? +n.slice(0, -1) : "", loose: false, items: [] };
2297
- n = r ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = r ? n : "[*+-]");
2298
- let s = this.rules.other.listItemRegex(n), a = false;
2299
- for (; e; ) {
2300
- let p = false, u = "", c = "";
2301
- if (!(t = s.exec(e)) || this.rules.block.hr.test(e)) break;
2302
- u = t[0], e = e.substring(u.length);
2303
- let g = t[2].split(`
2304
- `, 1)[0].replace(this.rules.other.listReplaceTabs, (H) => " ".repeat(3 * H.length)), h = e.split(`
2305
- `, 1)[0], R = !g.trim(), f = 0;
2306
- if (this.options.pedantic ? (f = 2, c = g.trimStart()) : R ? f = t[1].length + 1 : (f = t[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = g.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (u += h + `
2307
- `, e = e.substring(h.length + 1), p = true), !p) {
2308
- let H = 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);
2309
- for (; e; ) {
2310
- let Z = e.split(`
2311
- `, 1)[0], A;
2312
- if (h = Z, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A = h) : A = h.replace(this.rules.other.tabCharGlobal, " "), te.test(h) || ne.test(h) || xe.test(h) || H.test(h) || ee.test(h)) break;
2313
- if (A.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) c += `
2314
- ` + A.slice(f);
2315
- else {
2316
- if (R || g.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || te.test(g) || ne.test(g) || ee.test(g)) break;
2317
- c += `
2318
- ` + h;
2319
- }
2320
- !R && !h.trim() && (R = true), u += Z + `
2321
- `, e = e.substring(Z.length + 1), g = A.slice(f);
2322
- }
2323
- }
2324
- i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(u) && (a = true));
2325
- let O = null, Y;
2326
- this.options.gfm && (O = this.rules.other.listIsTask.exec(c), O && (Y = O[0] !== "[ ] ", c = c.replace(this.rules.other.listReplaceTask, ""))), i.items.push({ type: "list_item", raw: u, task: !!O, checked: Y, loose: false, text: c, tokens: [] }), i.raw += u;
2327
- }
2328
- let o = i.items.at(-1);
2329
- if (o) o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd();
2330
- else return;
2331
- i.raw = i.raw.trimEnd();
2332
- for (let p = 0; p < i.items.length; p++) if (this.lexer.state.top = false, i.items[p].tokens = this.lexer.blockTokens(i.items[p].text, []), !i.loose) {
2333
- let u = i.items[p].tokens.filter((g) => g.type === "space"), c = u.length > 0 && u.some((g) => this.rules.other.anyLine.test(g.raw));
2334
- i.loose = c;
2335
- }
2336
- if (i.loose) for (let p = 0; p < i.items.length; p++) i.items[p].loose = true;
2337
- return i;
2338
- }
2339
- }
2340
- html(e) {
2341
- let t = this.rules.block.html.exec(e);
2342
- if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
2343
- }
2344
- def(e) {
2345
- let t = this.rules.block.def.exec(e);
2346
- if (t) {
2347
- let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), r = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
2348
- return { type: "def", tag: n, raw: t[0], href: r, title: i };
2349
- }
2350
- }
2351
- table(e) {
2352
- let t = this.rules.block.table.exec(e);
2353
- if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
2354
- let n = V(t[1]), r = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
2355
- `) : [], s = { type: "table", raw: t[0], header: [], align: [], rows: [] };
2356
- if (n.length === r.length) {
2357
- for (let a of r) this.rules.other.tableAlignRight.test(a) ? s.align.push("right") : this.rules.other.tableAlignCenter.test(a) ? s.align.push("center") : this.rules.other.tableAlignLeft.test(a) ? s.align.push("left") : s.align.push(null);
2358
- for (let a = 0; a < n.length; a++) s.header.push({ text: n[a], tokens: this.lexer.inline(n[a]), header: true, align: s.align[a] });
2359
- for (let a of i) s.rows.push(V(a, s.header.length).map((o, p) => ({ text: o, tokens: this.lexer.inline(o), header: false, align: s.align[p] })));
2360
- return s;
2361
- }
2362
- }
2363
- lheading(e) {
2364
- let t = this.rules.block.lheading.exec(e);
2365
- if (t) return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) };
2366
- }
2367
- paragraph(e) {
2368
- let t = this.rules.block.paragraph.exec(e);
2369
- if (t) {
2370
- let n = t[1].charAt(t[1].length - 1) === `
2371
- ` ? t[1].slice(0, -1) : t[1];
2372
- return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
2373
- }
2374
- }
2375
- text(e) {
2376
- let t = this.rules.block.text.exec(e);
2377
- if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
2378
- }
2379
- escape(e) {
2380
- let t = this.rules.inline.escape.exec(e);
2381
- if (t) return { type: "escape", raw: t[0], text: t[1] };
2382
- }
2383
- tag(e) {
2384
- let t = this.rules.inline.tag.exec(e);
2385
- if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
2386
- }
2387
- link(e) {
2388
- let t = this.rules.inline.link.exec(e);
2389
- if (t) {
2390
- let n = t[2].trim();
2391
- if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
2392
- if (!this.rules.other.endAngleBracket.test(n)) return;
2393
- let s = z(n.slice(0, -1), "\\");
2394
- if ((n.length - s.length) % 2 === 0) return;
2395
- } else {
2396
- let s = fe(t[2], "()");
2397
- if (s === -2) return;
2398
- if (s > -1) {
2399
- let o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + s;
2400
- t[2] = t[2].substring(0, s), t[0] = t[0].substring(0, o).trim(), t[3] = "";
2401
- }
2402
- }
2403
- let r = t[2], i = "";
2404
- if (this.options.pedantic) {
2405
- let s = this.rules.other.pedanticHrefTitle.exec(r);
2406
- s && (r = s[1], i = s[3]);
2407
- } else i = t[3] ? t[3].slice(1, -1) : "";
2408
- return r = r.trim(), this.rules.other.startAngleBracket.test(r) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? r = r.slice(1) : r = r.slice(1, -1)), me(t, { href: r && r.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
2409
- }
2410
- }
2411
- reflink(e, t) {
2412
- let n;
2413
- if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
2414
- let r = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[r.toLowerCase()];
2415
- if (!i) {
2416
- let s = n[0].charAt(0);
2417
- return { type: "text", raw: s, text: s };
2418
- }
2419
- return me(n, i, n[0], this.lexer, this.rules);
2420
- }
2421
- }
2422
- emStrong(e, t, n = "") {
2423
- let r = this.rules.inline.emStrongLDelim.exec(e);
2424
- if (!r || r[3] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
2425
- if (!(r[1] || r[2] || "") || !n || this.rules.inline.punctuation.exec(n)) {
2426
- let s = [...r[0]].length - 1, a, o, p = s, u = 0, c = r[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
2427
- for (c.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = c.exec(t)) != null; ) {
2428
- if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a) continue;
2429
- if (o = [...a].length, r[3] || r[4]) {
2430
- p += o;
2431
- continue;
2432
- } else if ((r[5] || r[6]) && s % 3 && !((s + o) % 3)) {
2433
- u += o;
2434
- continue;
2435
- }
2436
- if (p -= o, p > 0) continue;
2437
- o = Math.min(o, o + p + u);
2438
- let g = [...r[0]][0].length, h = e.slice(0, s + r.index + g + o);
2439
- if (Math.min(s, o) % 2) {
2440
- let f = h.slice(1, -1);
2441
- return { type: "em", raw: h, text: f, tokens: this.lexer.inlineTokens(f) };
2442
- }
2443
- let R = h.slice(2, -2);
2444
- return { type: "strong", raw: h, text: R, tokens: this.lexer.inlineTokens(R) };
2445
- }
2446
- }
2447
- }
2448
- codespan(e) {
2449
- let t = this.rules.inline.code.exec(e);
2450
- if (t) {
2451
- let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), r = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
2452
- return r && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
2453
- }
2454
- }
2455
- br(e) {
2456
- let t = this.rules.inline.br.exec(e);
2457
- if (t) return { type: "br", raw: t[0] };
2458
- }
2459
- del(e) {
2460
- let t = this.rules.inline.del.exec(e);
2461
- if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) };
2462
- }
2463
- autolink(e) {
2464
- let t = this.rules.inline.autolink.exec(e);
2465
- if (t) {
2466
- let n, r;
2467
- return t[2] === "@" ? (n = t[1], r = "mailto:" + n) : (n = t[1], r = n), { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
2468
- }
2469
- }
2470
- url(e) {
2471
- let t;
2472
- if (t = this.rules.inline.url.exec(e)) {
2473
- let n, r;
2474
- if (t[2] === "@") n = t[0], r = "mailto:" + n;
2475
- else {
2476
- let i;
2477
- do
2478
- i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
2479
- while (i !== t[0]);
2480
- n = t[0], t[1] === "www." ? r = "http://" + t[0] : r = t[0];
2481
- }
2482
- return { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
2483
- }
2484
- }
2485
- inlineText(e) {
2486
- let t = this.rules.inline.text.exec(e);
2487
- if (t) {
2488
- let n = this.lexer.state.inRawBlock;
2489
- return { type: "text", raw: t[0], text: t[0], escaped: n };
2490
- }
2491
- }
2492
- };
2493
- var x = class l {
2494
- tokens;
2495
- options;
2496
- state;
2497
- tokenizer;
2498
- inlineQueue;
2499
- constructor(e) {
2500
- this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
2501
- let t = { other: m, block: C.normal, inline: M.normal };
2502
- this.options.pedantic ? (t.block = C.pedantic, t.inline = M.pedantic) : this.options.gfm && (t.block = C.gfm, this.options.breaks ? t.inline = M.breaks : t.inline = M.gfm), this.tokenizer.rules = t;
2503
- }
2504
- static get rules() {
2505
- return { block: C, inline: M };
2506
- }
2507
- static lex(e, t) {
2508
- return new l(t).lex(e);
2509
- }
2510
- static lexInline(e, t) {
2511
- return new l(t).inlineTokens(e);
2512
- }
2513
- lex(e) {
2514
- e = e.replace(m.carriageReturn, `
2515
- `), this.blockTokens(e, this.tokens);
2516
- for (let t = 0; t < this.inlineQueue.length; t++) {
2517
- let n = this.inlineQueue[t];
2518
- this.inlineTokens(n.src, n.tokens);
2519
- }
2520
- return this.inlineQueue = [], this.tokens;
2521
- }
2522
- blockTokens(e, t = [], n = false) {
2523
- for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
2524
- let r;
2525
- if (this.options.extensions?.block?.some((s) => (r = s.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
2526
- if (r = this.tokenizer.space(e)) {
2527
- e = e.substring(r.raw.length);
2528
- let s = t.at(-1);
2529
- r.raw.length === 1 && s !== void 0 ? s.raw += `
2530
- ` : t.push(r);
2531
- continue;
2532
- }
2533
- if (r = this.tokenizer.code(e)) {
2534
- e = e.substring(r.raw.length);
2535
- let s = t.at(-1);
2536
- s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
2537
- `) ? "" : `
2538
- `) + r.raw, s.text += `
2539
- ` + r.text, this.inlineQueue.at(-1).src = s.text) : t.push(r);
2540
- continue;
2541
- }
2542
- if (r = this.tokenizer.fences(e)) {
2543
- e = e.substring(r.raw.length), t.push(r);
2544
- continue;
2545
- }
2546
- if (r = this.tokenizer.heading(e)) {
2547
- e = e.substring(r.raw.length), t.push(r);
2548
- continue;
2549
- }
2550
- if (r = this.tokenizer.hr(e)) {
2551
- e = e.substring(r.raw.length), t.push(r);
2552
- continue;
2553
- }
2554
- if (r = this.tokenizer.blockquote(e)) {
2555
- e = e.substring(r.raw.length), t.push(r);
2556
- continue;
2557
- }
2558
- if (r = this.tokenizer.list(e)) {
2559
- e = e.substring(r.raw.length), t.push(r);
2560
- continue;
2561
- }
2562
- if (r = this.tokenizer.html(e)) {
2563
- e = e.substring(r.raw.length), t.push(r);
2564
- continue;
2565
- }
2566
- if (r = this.tokenizer.def(e)) {
2567
- e = e.substring(r.raw.length);
2568
- let s = t.at(-1);
2569
- s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
2570
- `) ? "" : `
2571
- `) + r.raw, s.text += `
2572
- ` + r.raw, this.inlineQueue.at(-1).src = s.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
2573
- continue;
2574
- }
2575
- if (r = this.tokenizer.table(e)) {
2576
- e = e.substring(r.raw.length), t.push(r);
2577
- continue;
2578
- }
2579
- if (r = this.tokenizer.lheading(e)) {
2580
- e = e.substring(r.raw.length), t.push(r);
2581
- continue;
2582
- }
2583
- let i = e;
2584
- if (this.options.extensions?.startBlock) {
2585
- let s = 1 / 0, a = e.slice(1), o;
2586
- this.options.extensions.startBlock.forEach((p) => {
2587
- o = p.call({ lexer: this }, a), typeof o == "number" && o >= 0 && (s = Math.min(s, o));
2588
- }), s < 1 / 0 && s >= 0 && (i = e.substring(0, s + 1));
2589
- }
2590
- if (this.state.top && (r = this.tokenizer.paragraph(i))) {
2591
- let s = t.at(-1);
2592
- n && s?.type === "paragraph" ? (s.raw += (s.raw.endsWith(`
2593
- `) ? "" : `
2594
- `) + r.raw, s.text += `
2595
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
2596
- continue;
2597
- }
2598
- if (r = this.tokenizer.text(e)) {
2599
- e = e.substring(r.raw.length);
2600
- let s = t.at(-1);
2601
- s?.type === "text" ? (s.raw += (s.raw.endsWith(`
2602
- `) ? "" : `
2603
- `) + r.raw, s.text += `
2604
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r);
2605
- continue;
2606
- }
2607
- if (e) {
2608
- let s = "Infinite loop on byte: " + e.charCodeAt(0);
2609
- if (this.options.silent) {
2610
- console.error(s);
2611
- break;
2612
- } else throw new Error(s);
2613
- }
2614
- }
2615
- return this.state.top = true, t;
2616
- }
2617
- inline(e, t = []) {
2618
- return this.inlineQueue.push({ src: e, tokens: t }), t;
2619
- }
2620
- inlineTokens(e, t = []) {
2621
- let n = e, r = null;
2622
- if (this.tokens.links) {
2623
- let o = Object.keys(this.tokens.links);
2624
- if (o.length > 0) for (; (r = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(r[0].slice(r[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
2625
- }
2626
- for (; (r = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, r.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
2627
- let i;
2628
- for (; (r = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) i = r[2] ? r[2].length : 0, n = n.slice(0, r.index + i) + "[" + "a".repeat(r[0].length - i - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
2629
- n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
2630
- let s = false, a = "";
2631
- for (; e; ) {
2632
- s || (a = ""), s = false;
2633
- let o;
2634
- if (this.options.extensions?.inline?.some((u) => (o = u.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
2635
- if (o = this.tokenizer.escape(e)) {
2636
- e = e.substring(o.raw.length), t.push(o);
2637
- continue;
2638
- }
2639
- if (o = this.tokenizer.tag(e)) {
2640
- e = e.substring(o.raw.length), t.push(o);
2641
- continue;
2642
- }
2643
- if (o = this.tokenizer.link(e)) {
2644
- e = e.substring(o.raw.length), t.push(o);
2645
- continue;
2646
- }
2647
- if (o = this.tokenizer.reflink(e, this.tokens.links)) {
2648
- e = e.substring(o.raw.length);
2649
- let u = t.at(-1);
2650
- o.type === "text" && u?.type === "text" ? (u.raw += o.raw, u.text += o.text) : t.push(o);
2651
- continue;
2652
- }
2653
- if (o = this.tokenizer.emStrong(e, n, a)) {
2654
- e = e.substring(o.raw.length), t.push(o);
2655
- continue;
2656
- }
2657
- if (o = this.tokenizer.codespan(e)) {
2658
- e = e.substring(o.raw.length), t.push(o);
2659
- continue;
2660
- }
2661
- if (o = this.tokenizer.br(e)) {
2662
- e = e.substring(o.raw.length), t.push(o);
2663
- continue;
2664
- }
2665
- if (o = this.tokenizer.del(e)) {
2666
- e = e.substring(o.raw.length), t.push(o);
2667
- continue;
2668
- }
2669
- if (o = this.tokenizer.autolink(e)) {
2670
- e = e.substring(o.raw.length), t.push(o);
2671
- continue;
2672
- }
2673
- if (!this.state.inLink && (o = this.tokenizer.url(e))) {
2674
- e = e.substring(o.raw.length), t.push(o);
2675
- continue;
2676
- }
2677
- let p = e;
2678
- if (this.options.extensions?.startInline) {
2679
- let u = 1 / 0, c = e.slice(1), g;
2680
- this.options.extensions.startInline.forEach((h) => {
2681
- g = h.call({ lexer: this }, c), typeof g == "number" && g >= 0 && (u = Math.min(u, g));
2682
- }), u < 1 / 0 && u >= 0 && (p = e.substring(0, u + 1));
2683
- }
2684
- if (o = this.tokenizer.inlineText(p)) {
2685
- e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (a = o.raw.slice(-1)), s = true;
2686
- let u = t.at(-1);
2687
- u?.type === "text" ? (u.raw += o.raw, u.text += o.text) : t.push(o);
2688
- continue;
2689
- }
2690
- if (e) {
2691
- let u = "Infinite loop on byte: " + e.charCodeAt(0);
2692
- if (this.options.silent) {
2693
- console.error(u);
2694
- break;
2695
- } else throw new Error(u);
2696
- }
2697
- }
2698
- return t;
2699
- }
2700
- };
2701
- var P = class {
2702
- options;
2703
- parser;
2704
- constructor(e) {
2705
- this.options = e || T;
2706
- }
2707
- space(e) {
2708
- return "";
2709
- }
2710
- code({ text: e, lang: t, escaped: n }) {
2711
- let r = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
2712
- `;
2713
- return r ? '<pre><code class="language-' + w(r) + '">' + (n ? i : w(i, true)) + `</code></pre>
2714
- ` : "<pre><code>" + (n ? i : w(i, true)) + `</code></pre>
2715
- `;
2716
- }
2717
- blockquote({ tokens: e }) {
2718
- return `<blockquote>
2719
- ${this.parser.parse(e)}</blockquote>
2720
- `;
2721
- }
2722
- html({ text: e }) {
2723
- return e;
2724
- }
2725
- def(e) {
2726
- return "";
2727
- }
2728
- heading({ tokens: e, depth: t }) {
2729
- return `<h${t}>${this.parser.parseInline(e)}</h${t}>
2730
- `;
2731
- }
2732
- hr(e) {
2733
- return `<hr>
2734
- `;
2735
- }
2736
- list(e) {
2737
- let t = e.ordered, n = e.start, r = "";
2738
- for (let a = 0; a < e.items.length; a++) {
2739
- let o = e.items[a];
2740
- r += this.listitem(o);
2741
- }
2742
- let i = t ? "ol" : "ul", s = t && n !== 1 ? ' start="' + n + '"' : "";
2743
- return "<" + i + s + `>
2744
- ` + r + "</" + i + `>
2745
- `;
2746
- }
2747
- listitem(e) {
2748
- let t = "";
2749
- if (e.task) {
2750
- let n = this.checkbox({ checked: !!e.checked });
2751
- e.loose ? e.tokens[0]?.type === "paragraph" ? (e.tokens[0].text = n + " " + e.tokens[0].text, e.tokens[0].tokens && e.tokens[0].tokens.length > 0 && e.tokens[0].tokens[0].type === "text" && (e.tokens[0].tokens[0].text = n + " " + w(e.tokens[0].tokens[0].text), e.tokens[0].tokens[0].escaped = true)) : e.tokens.unshift({ type: "text", raw: n + " ", text: n + " ", escaped: true }) : t += n + " ";
2752
- }
2753
- return t += this.parser.parse(e.tokens, !!e.loose), `<li>${t}</li>
2754
- `;
2755
- }
2756
- checkbox({ checked: e }) {
2757
- return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
2758
- }
2759
- paragraph({ tokens: e }) {
2760
- return `<p>${this.parser.parseInline(e)}</p>
2761
- `;
2762
- }
2763
- table(e) {
2764
- let t = "", n = "";
2765
- for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
2766
- t += this.tablerow({ text: n });
2767
- let r = "";
2768
- for (let i = 0; i < e.rows.length; i++) {
2769
- let s = e.rows[i];
2770
- n = "";
2771
- for (let a = 0; a < s.length; a++) n += this.tablecell(s[a]);
2772
- r += this.tablerow({ text: n });
2773
- }
2774
- return r && (r = `<tbody>${r}</tbody>`), `<table>
2775
- <thead>
2776
- ` + t + `</thead>
2777
- ` + r + `</table>
2778
- `;
2779
- }
2780
- tablerow({ text: e }) {
2781
- return `<tr>
2782
- ${e}</tr>
2783
- `;
2784
- }
2785
- tablecell(e) {
2786
- let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
2787
- return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
2788
- `;
2789
- }
2790
- strong({ tokens: e }) {
2791
- return `<strong>${this.parser.parseInline(e)}</strong>`;
2792
- }
2793
- em({ tokens: e }) {
2794
- return `<em>${this.parser.parseInline(e)}</em>`;
2795
- }
2796
- codespan({ text: e }) {
2797
- return `<code>${w(e, true)}</code>`;
2798
- }
2799
- br(e) {
2800
- return "<br>";
2801
- }
2802
- del({ tokens: e }) {
2803
- return `<del>${this.parser.parseInline(e)}</del>`;
2804
- }
2805
- link({ href: e, title: t, tokens: n }) {
2806
- let r = this.parser.parseInline(n), i = J(e);
2807
- if (i === null) return r;
2808
- e = i;
2809
- let s = '<a href="' + e + '"';
2810
- return t && (s += ' title="' + w(t) + '"'), s += ">" + r + "</a>", s;
2811
- }
2812
- image({ href: e, title: t, text: n, tokens: r }) {
2813
- r && (n = this.parser.parseInline(r, this.parser.textRenderer));
2814
- let i = J(e);
2815
- if (i === null) return w(n);
2816
- e = i;
2817
- let s = `<img src="${e}" alt="${n}"`;
2818
- return t && (s += ` title="${w(t)}"`), s += ">", s;
2819
- }
2820
- text(e) {
2821
- return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : w(e.text);
2822
- }
2823
- };
2824
- var $ = class {
2825
- strong({ text: e }) {
2826
- return e;
2827
- }
2828
- em({ text: e }) {
2829
- return e;
2830
- }
2831
- codespan({ text: e }) {
2832
- return e;
2833
- }
2834
- del({ text: e }) {
2835
- return e;
2836
- }
2837
- html({ text: e }) {
2838
- return e;
2839
- }
2840
- text({ text: e }) {
2841
- return e;
2842
- }
2843
- link({ text: e }) {
2844
- return "" + e;
2845
- }
2846
- image({ text: e }) {
2847
- return "" + e;
2848
- }
2849
- br() {
2850
- return "";
2851
- }
2852
- };
2853
- var b = class l2 {
2854
- options;
2855
- renderer;
2856
- textRenderer;
2857
- constructor(e) {
2858
- this.options = e || T, this.options.renderer = this.options.renderer || new P(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new $();
2859
- }
2860
- static parse(e, t) {
2861
- return new l2(t).parse(e);
2862
- }
2863
- static parseInline(e, t) {
2864
- return new l2(t).parseInline(e);
2865
- }
2866
- parse(e, t = true) {
2867
- let n = "";
2868
- for (let r = 0; r < e.length; r++) {
2869
- let i = e[r];
2870
- if (this.options.extensions?.renderers?.[i.type]) {
2871
- let a = i, o = this.options.extensions.renderers[a.type].call({ parser: this }, a);
2872
- if (o !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(a.type)) {
2873
- n += o || "";
2874
- continue;
2875
- }
2876
- }
2877
- let s = i;
2878
- switch (s.type) {
2879
- case "space": {
2880
- n += this.renderer.space(s);
2881
- continue;
2882
- }
2883
- case "hr": {
2884
- n += this.renderer.hr(s);
2885
- continue;
2886
- }
2887
- case "heading": {
2888
- n += this.renderer.heading(s);
2889
- continue;
2890
- }
2891
- case "code": {
2892
- n += this.renderer.code(s);
2893
- continue;
2894
- }
2895
- case "table": {
2896
- n += this.renderer.table(s);
2897
- continue;
2898
- }
2899
- case "blockquote": {
2900
- n += this.renderer.blockquote(s);
2901
- continue;
2902
- }
2903
- case "list": {
2904
- n += this.renderer.list(s);
2905
- continue;
2906
- }
2907
- case "html": {
2908
- n += this.renderer.html(s);
2909
- continue;
2910
- }
2911
- case "def": {
2912
- n += this.renderer.def(s);
2913
- continue;
2914
- }
2915
- case "paragraph": {
2916
- n += this.renderer.paragraph(s);
2917
- continue;
2918
- }
2919
- case "text": {
2920
- let a = s, o = this.renderer.text(a);
2921
- for (; r + 1 < e.length && e[r + 1].type === "text"; ) a = e[++r], o += `
2922
- ` + this.renderer.text(a);
2923
- t ? n += this.renderer.paragraph({ type: "paragraph", raw: o, text: o, tokens: [{ type: "text", raw: o, text: o, escaped: true }] }) : n += o;
2924
- continue;
2925
- }
2926
- default: {
2927
- let a = 'Token with "' + s.type + '" type was not found.';
2928
- if (this.options.silent) return console.error(a), "";
2929
- throw new Error(a);
2930
- }
2931
- }
2932
- }
2933
- return n;
2934
- }
2935
- parseInline(e, t = this.renderer) {
2936
- let n = "";
2937
- for (let r = 0; r < e.length; r++) {
2938
- let i = e[r];
2939
- if (this.options.extensions?.renderers?.[i.type]) {
2940
- let a = this.options.extensions.renderers[i.type].call({ parser: this }, i);
2941
- if (a !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
2942
- n += a || "";
2943
- continue;
2944
- }
2945
- }
2946
- let s = i;
2947
- switch (s.type) {
2948
- case "escape": {
2949
- n += t.text(s);
2950
- break;
2951
- }
2952
- case "html": {
2953
- n += t.html(s);
2954
- break;
2955
- }
2956
- case "link": {
2957
- n += t.link(s);
2958
- break;
2959
- }
2960
- case "image": {
2961
- n += t.image(s);
2962
- break;
2963
- }
2964
- case "strong": {
2965
- n += t.strong(s);
2966
- break;
2967
- }
2968
- case "em": {
2969
- n += t.em(s);
2970
- break;
2971
- }
2972
- case "codespan": {
2973
- n += t.codespan(s);
2974
- break;
2975
- }
2976
- case "br": {
2977
- n += t.br(s);
2978
- break;
2979
- }
2980
- case "del": {
2981
- n += t.del(s);
2982
- break;
2983
- }
2984
- case "text": {
2985
- n += t.text(s);
2986
- break;
2987
- }
2988
- default: {
2989
- let a = 'Token with "' + s.type + '" type was not found.';
2990
- if (this.options.silent) return console.error(a), "";
2991
- throw new Error(a);
2992
- }
2993
- }
2994
- }
2995
- return n;
2996
- }
2997
- };
2998
- var S = class {
2999
- options;
3000
- block;
3001
- constructor(e) {
3002
- this.options = e || T;
3003
- }
3004
- static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
3005
- static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
3006
- preprocess(e) {
3007
- return e;
3008
- }
3009
- postprocess(e) {
3010
- return e;
3011
- }
3012
- processAllTokens(e) {
3013
- return e;
3014
- }
3015
- emStrongMask(e) {
3016
- return e;
3017
- }
3018
- provideLexer() {
3019
- return this.block ? x.lex : x.lexInline;
3020
- }
3021
- provideParser() {
3022
- return this.block ? b.parse : b.parseInline;
3023
- }
3024
- };
3025
- var B = class {
3026
- defaults = L();
3027
- options = this.setOptions;
3028
- parse = this.parseMarkdown(true);
3029
- parseInline = this.parseMarkdown(false);
3030
- Parser = b;
3031
- Renderer = P;
3032
- TextRenderer = $;
3033
- Lexer = x;
3034
- Tokenizer = y;
3035
- Hooks = S;
3036
- constructor(...e) {
3037
- this.use(...e);
3038
- }
3039
- walkTokens(e, t) {
3040
- let n = [];
3041
- for (let r of e) switch (n = n.concat(t.call(this, r)), r.type) {
3042
- case "table": {
3043
- let i = r;
3044
- for (let s of i.header) n = n.concat(this.walkTokens(s.tokens, t));
3045
- for (let s of i.rows) for (let a of s) n = n.concat(this.walkTokens(a.tokens, t));
3046
- break;
3047
- }
3048
- case "list": {
3049
- let i = r;
3050
- n = n.concat(this.walkTokens(i.items, t));
3051
- break;
3052
- }
3053
- default: {
3054
- let i = r;
3055
- this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((s) => {
3056
- let a = i[s].flat(1 / 0);
3057
- n = n.concat(this.walkTokens(a, t));
3058
- }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
3059
- }
3060
- }
3061
- return n;
3062
- }
3063
- use(...e) {
3064
- let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
3065
- return e.forEach((n) => {
3066
- let r = { ...n };
3067
- if (r.async = this.defaults.async || r.async || false, n.extensions && (n.extensions.forEach((i) => {
3068
- if (!i.name) throw new Error("extension name required");
3069
- if ("renderer" in i) {
3070
- let s = t.renderers[i.name];
3071
- s ? t.renderers[i.name] = function(...a) {
3072
- let o = i.renderer.apply(this, a);
3073
- return o === false && (o = s.apply(this, a)), o;
3074
- } : t.renderers[i.name] = i.renderer;
3075
- }
3076
- if ("tokenizer" in i) {
3077
- if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
3078
- let s = t[i.level];
3079
- s ? s.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
3080
- }
3081
- "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
3082
- }), r.extensions = t), n.renderer) {
3083
- let i = this.defaults.renderer || new P(this.defaults);
3084
- for (let s in n.renderer) {
3085
- if (!(s in i)) throw new Error(`renderer '${s}' does not exist`);
3086
- if (["options", "parser"].includes(s)) continue;
3087
- let a = s, o = n.renderer[a], p = i[a];
3088
- i[a] = (...u) => {
3089
- let c = o.apply(i, u);
3090
- return c === false && (c = p.apply(i, u)), c || "";
3091
- };
3092
- }
3093
- r.renderer = i;
3094
- }
3095
- if (n.tokenizer) {
3096
- let i = this.defaults.tokenizer || new y(this.defaults);
3097
- for (let s in n.tokenizer) {
3098
- if (!(s in i)) throw new Error(`tokenizer '${s}' does not exist`);
3099
- if (["options", "rules", "lexer"].includes(s)) continue;
3100
- let a = s, o = n.tokenizer[a], p = i[a];
3101
- i[a] = (...u) => {
3102
- let c = o.apply(i, u);
3103
- return c === false && (c = p.apply(i, u)), c;
3104
- };
3105
- }
3106
- r.tokenizer = i;
3107
- }
3108
- if (n.hooks) {
3109
- let i = this.defaults.hooks || new S();
3110
- for (let s in n.hooks) {
3111
- if (!(s in i)) throw new Error(`hook '${s}' does not exist`);
3112
- if (["options", "block"].includes(s)) continue;
3113
- let a = s, o = n.hooks[a], p = i[a];
3114
- S.passThroughHooks.has(s) ? i[a] = (u) => {
3115
- if (this.defaults.async && S.passThroughHooksRespectAsync.has(s)) return (async () => {
3116
- let g = await o.call(i, u);
3117
- return p.call(i, g);
3118
- })();
3119
- let c = o.call(i, u);
3120
- return p.call(i, c);
3121
- } : i[a] = (...u) => {
3122
- if (this.defaults.async) return (async () => {
3123
- let g = await o.apply(i, u);
3124
- return g === false && (g = await p.apply(i, u)), g;
3125
- })();
3126
- let c = o.apply(i, u);
3127
- return c === false && (c = p.apply(i, u)), c;
3128
- };
3129
- }
3130
- r.hooks = i;
3131
- }
3132
- if (n.walkTokens) {
3133
- let i = this.defaults.walkTokens, s = n.walkTokens;
3134
- r.walkTokens = function(a) {
3135
- let o = [];
3136
- return o.push(s.call(this, a)), i && (o = o.concat(i.call(this, a))), o;
3137
- };
3138
- }
3139
- this.defaults = { ...this.defaults, ...r };
3140
- }), this;
3141
- }
3142
- setOptions(e) {
3143
- return this.defaults = { ...this.defaults, ...e }, this;
3144
- }
3145
- lexer(e, t) {
3146
- return x.lex(e, t ?? this.defaults);
3147
- }
3148
- parser(e, t) {
3149
- return b.parse(e, t ?? this.defaults);
3150
- }
3151
- parseMarkdown(e) {
3152
- return (n, r) => {
3153
- let i = { ...r }, s = { ...this.defaults, ...i }, a = this.onError(!!s.silent, !!s.async);
3154
- if (this.defaults.async === true && i.async === false) return a(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."));
3155
- if (typeof n > "u" || n === null) return a(new Error("marked(): input parameter is undefined or null"));
3156
- if (typeof n != "string") return a(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
3157
- if (s.hooks && (s.hooks.options = s, s.hooks.block = e), s.async) return (async () => {
3158
- let o = s.hooks ? await s.hooks.preprocess(n) : n, u = await (s.hooks ? await s.hooks.provideLexer() : e ? x.lex : x.lexInline)(o, s), c = s.hooks ? await s.hooks.processAllTokens(u) : u;
3159
- s.walkTokens && await Promise.all(this.walkTokens(c, s.walkTokens));
3160
- let h = await (s.hooks ? await s.hooks.provideParser() : e ? b.parse : b.parseInline)(c, s);
3161
- return s.hooks ? await s.hooks.postprocess(h) : h;
3162
- })().catch(a);
3163
- try {
3164
- s.hooks && (n = s.hooks.preprocess(n));
3165
- let p = (s.hooks ? s.hooks.provideLexer() : e ? x.lex : x.lexInline)(n, s);
3166
- s.hooks && (p = s.hooks.processAllTokens(p)), s.walkTokens && this.walkTokens(p, s.walkTokens);
3167
- let c = (s.hooks ? s.hooks.provideParser() : e ? b.parse : b.parseInline)(p, s);
3168
- return s.hooks && (c = s.hooks.postprocess(c)), c;
3169
- } catch (o) {
3170
- return a(o);
3171
- }
3172
- };
3173
- }
3174
- onError(e, t) {
3175
- return (n) => {
3176
- if (n.message += `
3177
- Please report this to https://github.com/markedjs/marked.`, e) {
3178
- let r = "<p>An error occurred:</p><pre>" + w(n.message + "", true) + "</pre>";
3179
- return t ? Promise.resolve(r) : r;
3180
- }
3181
- if (t) return Promise.reject(n);
3182
- throw n;
3183
- };
3184
- }
3185
- };
3186
- var _ = new B();
3187
- function k(l3, e) {
3188
- return _.parse(l3, e);
3189
- }
3190
- k.options = k.setOptions = function(l3) {
3191
- return _.setOptions(l3), k.defaults = _.defaults, G(k.defaults), k;
3192
- };
3193
- k.getDefaults = L;
3194
- k.defaults = T;
3195
- k.use = function(...l3) {
3196
- return _.use(...l3), k.defaults = _.defaults, G(k.defaults), k;
3197
- };
3198
- k.walkTokens = function(l3, e) {
3199
- return _.walkTokens(l3, e);
3200
- };
3201
- k.parseInline = _.parseInline;
3202
- k.Parser = b;
3203
- k.parser = b.parse;
3204
- k.Renderer = P;
3205
- k.TextRenderer = $;
3206
- k.Lexer = x;
3207
- k.lexer = x.lex;
3208
- k.Tokenizer = y;
3209
- k.Hooks = S;
3210
- k.parse = k;
3211
- var Zt = k.options;
3212
- var Gt = k.setOptions;
3213
- var Nt = k.use;
3214
- var Ft = k.walkTokens;
3215
- var jt = k.parseInline;
3216
- var Ut = b.parse;
3217
- var Kt = x.lex;
3218
-
3219
- // src/markdown.ts
3220
- k.setOptions({
3221
- gfm: true,
3222
- breaks: true
3223
- });
3224
- var renderer = new k.Renderer();
3225
- renderer.link = ({ href, text: text2 }) => `<a href="${href}" target="_blank" rel="noopener noreferrer">${text2}</a>`;
3226
- renderer.html = () => "";
3227
- k.use({ renderer });
3228
- function renderMarkdown(text2) {
3229
- if (!text2) return "";
3230
- const html2 = k.parse(text2, { async: false });
3231
- return purify.sanitize(html2, {
3232
- ALLOWED_TAGS: [
3233
- "p",
3234
- "br",
3235
- "strong",
3236
- "b",
3237
- "em",
3238
- "i",
3239
- "s",
3240
- "del",
3241
- "code",
3242
- "pre",
3243
- "a",
3244
- "ul",
3245
- "ol",
3246
- "li",
3247
- "h1",
3248
- "h2",
3249
- "h3",
3250
- "h4",
3251
- "h5",
3252
- "h6",
3253
- "blockquote",
3254
- "span"
3255
- ],
3256
- ALLOWED_ATTR: ["href", "target", "rel", "class"]
3257
- });
3258
- }
3259
-
3260
- // src/element-event-controller.ts
3261
- var AssistantElementEventController = class {
3262
- #host;
3263
- #assistantBody;
3264
- #assistantText = "";
3265
- #completedTool;
3266
- #streamKind;
3267
- #proposalCards = /* @__PURE__ */ new Map();
3268
- constructor(host) {
3269
- this.#host = host;
3270
- }
3271
- handle(event) {
3272
- if (event.event === "view_available") {
3273
- this.#host.element.dispatchEvent(
3274
- new CustomEvent("assistant-view-available", {
3275
- detail: event.data
3276
- })
3277
- );
3278
- return;
3279
- }
3280
- if (event.event === "unrecognized") return;
3281
- const { event: name, data } = event;
3282
- if (name === "session_started") {
3283
- if (isRecord(data.configuration)) {
3284
- this.#host.applyConfiguration(data.configuration);
3285
- }
3286
- this.#host.element.dispatchEvent(
3287
- new CustomEvent("assistant-session-started", {
3288
- detail: { expiresAt: String(data.expiresAt ?? "") }
3289
- })
3290
- );
3291
- return;
3292
- }
3293
- if (name === "session_expired") {
3294
- this.#host.element.dispatchEvent(new CustomEvent("assistant-session-expired"));
3295
- return;
3296
- }
3297
- if (name === "session_reset") {
3298
- this.resetConversation();
3299
- return;
3300
- }
3301
- if (name === "context_changed") {
3302
- this.#host.element.dispatchEvent(
3303
- new CustomEvent("assistant-context-changed", { detail: { context: data.context } })
3304
- );
3305
- return;
3306
- }
3307
- if (name === "model_context_changed") {
3308
- this.#host.element.dispatchEvent(
3309
- new CustomEvent("assistant-model-context-changed", {
3310
- detail: { modelContext: data.modelContext }
3311
- })
3312
- );
3313
- return;
3314
- }
3315
- if (name === "message_started") {
3316
- this.#startStream("message");
3317
- const body = this.#host.appendMessage("user", String(data.message ?? ""));
3318
- const messages = this.#host.messages();
3319
- if (body && messages) this.#revealLatestMessage(messages);
3320
- this.#host.element.dispatchEvent(new CustomEvent("assistant-message-started"));
3321
- return;
3322
- }
3323
- if (name === "message_completed") {
3324
- if (this.#streamKind !== "message") return;
3325
- this.#clearStream();
3326
- this.#host.element.dispatchEvent(new CustomEvent("assistant-message-completed"));
3327
- return;
3328
- }
3329
- if (name === "interaction_started") {
3330
- this.#startStream("interaction");
3331
- this.#completedTool = void 0;
3332
- return;
3333
- }
3334
- if (name === "interaction_completed") {
3335
- if (this.#streamKind !== "interaction") return;
3336
- this.#finishInteraction(String(data.id ?? ""), String(data.action ?? "accept"));
3337
- return;
3338
- }
3339
- if (name === "content") {
3340
- this.#appendContent(String(data.delta ?? ""));
3341
- return;
3342
- }
3343
- if (name === "tool_proposed" || name === "interaction_proposed") {
3344
- if (!this.#streamKind) return;
3345
- this.#appendToolProposal(
3346
- String(data.id ?? ""),
3347
- String(data.tool ?? ("title" in data ? data.title : void 0) ?? "Action"),
3348
- isRecord(data.arguments) ? data.arguments : void 0
3349
- );
3350
- return;
3351
- }
3352
- if (name === "input_requested" && isRecord(data.requestedSchema)) {
3353
- if (!this.#streamKind) return;
3354
- this.#appendInputRequest(
3355
- String(data.id ?? ""),
3356
- String(data.message ?? "More information is required"),
3357
- data.requestedSchema
3358
- );
3359
- return;
3360
- }
3361
- if (name === "tool_completed") {
3362
- this.#completedTool = data;
3363
- return;
3364
- }
3365
- if (name === "error") {
3366
- this.#clearStream();
3367
- this.#host.dispatchError({
3368
- code: String(data.code ?? "stream_failed"),
3369
- ...typeof data.status === "number" ? { status: data.status } : {},
3370
- retryable: data.retryable === true
3371
- });
3372
- }
3373
- }
3374
- resetConversation() {
3375
- const messages = this.#host.messages();
3376
- messages?.replaceChildren();
3377
- if (messages) messages.scrollTop = 0;
3378
- this.#proposalCards.clear();
3379
- this.#clearStream();
3380
- this.#completedTool = void 0;
3381
- this.#host.element.removeAttribute("has-messages");
3382
- this.#host.element.dispatchEvent(new CustomEvent("assistant-session-reset"));
3383
- }
3384
- #finishInteraction(id, action) {
3385
- if (this.#completedTool && !this.#assistantBody) {
3386
- this.#host.appendMessage("assistant", JSON.stringify(this.#completedTool.result ?? {}) ?? "");
3387
- }
3388
- this.#proposalCards.get(id)?.remove();
3389
- this.#proposalCards.delete(id);
3390
- if (action === "accept") {
3391
- this.#host.element.dispatchEvent(
3392
- new CustomEvent("assistant-tool-completed", { detail: { id } })
3393
- );
3394
- }
3395
- this.#host.element.dispatchEvent(
3396
- new CustomEvent("assistant-interaction-resolved", { detail: { id, action } })
3397
- );
3398
- this.#clearStream();
3399
- this.#completedTool = void 0;
3400
- }
3401
- #appendToolProposal(id, tool, arguments_) {
3402
- const messages = this.#host.messages();
3403
- if (!messages || !id) return;
3404
- this.#proposalCards.get(id)?.remove();
3405
- const labels = this.#host.labels();
3406
- const card = createInteractionCard({
3407
- tool,
3408
- ...arguments_ ? { arguments: arguments_ } : {},
3409
- labels: {
3410
- accept: labels.confirm,
3411
- decline: "Decline",
3412
- cancel: labels.cancel
3413
- },
3414
- respond: (action) => this.#host.respond(id, { action })
3415
- });
3416
- messages.append(card);
3417
- this.#proposalCards.set(id, card);
3418
- this.#revealLatestMessage(messages);
3419
- this.#host.element.dispatchEvent(
3420
- new CustomEvent("assistant-tool-proposed", { detail: { id, tool, arguments: arguments_ } })
3421
- );
3422
- }
3423
- #appendInputRequest(id, message, requestedSchema) {
3424
- const messages = this.#host.messages();
3425
- if (!messages || !id) return;
3426
- this.#proposalCards.get(id)?.remove();
3427
- const labels = this.#host.labels();
3428
- const card = createInputRequestCard({
3429
- message,
3430
- requestedSchema,
3431
- labels: {
3432
- submit: labels.confirm,
3433
- decline: "Decline",
3434
- cancel: labels.cancel
3435
- },
3436
- respond: (response) => this.#host.respond(id, response)
3437
- });
3438
- messages.append(card);
3439
- this.#proposalCards.set(id, card);
3440
- this.#revealLatestMessage(messages);
3441
- this.#host.element.dispatchEvent(
3442
- new CustomEvent("assistant-input-requested", {
3443
- detail: { id, message, requestedSchema }
3444
- })
3445
- );
3446
- }
3447
- #startStream(kind) {
3448
- this.#assistantBody = void 0;
3449
- this.#assistantText = "";
3450
- this.#streamKind = kind;
3451
- }
3452
- #clearStream() {
3453
- this.#assistantBody = void 0;
3454
- this.#assistantText = "";
3455
- this.#streamKind = void 0;
3456
- }
3457
- #appendContent(delta) {
3458
- if (!this.#streamKind || !delta) return;
3459
- this.#assistantText += delta;
3460
- const html2 = renderMarkdown(this.#assistantText);
3461
- if (!html2) return;
3462
- const body = this.#assistantBody ?? this.#host.appendMessage("assistant", "");
3463
- this.#assistantBody = body;
3464
- if (!body) return;
3465
- body.innerHTML = html2;
3466
- const messages = this.#host.messages();
3467
- if (messages) this.#revealLatestMessage(messages);
3468
- }
3469
- #revealLatestMessage(messages) {
3470
- this.#host.element.setAttribute("has-messages", "");
3471
- messages.scrollTop = messages.scrollHeight;
3472
- }
3473
- };
3474
- function isRecord(value) {
3475
- return typeof value === "object" && value !== null && !Array.isArray(value);
3476
- }
3477
-
3478
- // src/element-helpers.ts
3479
- function camelToKebab(value) {
3480
- return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
3481
- }
3482
- function tokenValue(name, value) {
3483
- if (typeof value !== "number") return value;
3484
- if (name === "lineHeight" || name === "motionScale") return String(value);
3485
- return `${value}px`;
3486
- }
3487
- function escapeAttribute(value) {
3488
- return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;");
3489
- }
3490
- function queryRequired(root, selector) {
3491
- const element = root.querySelector(selector);
3492
- if (!element) throw new Error(`assistant renderer is missing ${selector}`);
3493
- return element;
3494
- }
3495
-
3496
- // src/element-styles.ts
3497
- var ASSISTANT_ELEMENT_STYLES = `<style>
3498
- *, *::before, *::after { box-sizing: border-box; }
3499
- .visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }
3500
- .visually-hidden[hidden] { display: none !important; }
3501
- :host { color-scheme: light dark; font-family: var(--ns-assistant-font-family, var(--ns-assistant-default-font-family)); font-size: var(--ns-assistant-base-font-size, var(--ns-assistant-default-base-font-size)); line-height: var(--ns-assistant-line-height, var(--ns-assistant-default-line-height)); z-index: var(--ns-assistant-z-index, var(--ns-assistant-default-z-index)); -webkit-font-smoothing: antialiased; }
3502
- :host([data-mode="floating"]) { position: fixed; bottom: 20px; right: 20px; }
3503
- :host([data-mode="floating"][data-position="bottom-left"]) { right: auto; left: 20px; }
3504
- button { font: inherit; }
3505
- button, textarea, input, select { -webkit-tap-highlight-color: transparent; }
3506
- .launcher { display: grid; place-items: center; width: 48px; height: 48px; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 82%, transparent); box-shadow: 0 4px 20px rgba(0,0,0,.12); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); cursor: pointer; transition: transform .5s cubic-bezier(.25,1,.5,1), box-shadow .2s ease; }
3507
- .launcher:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 8px 26px rgba(0,0,0,.16); }
3508
- .launcher img { width: 28px; height: 28px; border-radius: 50%; object-fit: contain; }
3509
- .panel { display: none; flex-direction: column; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 40px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 40px)); overflow: hidden; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 88%, transparent); border: 1px solid color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 74%, transparent); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); transform-origin: bottom right; animation: halo-panel-in .32s cubic-bezier(.23,1,.32,1) both; }
3510
- :host([open]) .panel { display: flex; }
3511
- :host([open]) .launcher { display: none; }
3512
- header { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; min-height: 64px; padding: 14px 18px; border-bottom: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }
3513
- header strong { flex: 1; font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
3514
- .brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }
3515
- .close, .send { display: grid; place-items: center; border: 0; border-radius: 999px; cursor: pointer; }
3516
- .close { width: 32px; height: 32px; padding: 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; font-size: 24px; font-weight: 300; line-height: 1; transition: background .15s ease, color .15s ease; }
3517
- .close:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }
3518
- .welcome { flex: 0 0 auto; padding: 30px 22px 18px; }
3519
- .welcome h2 { margin: 0; font-size: 1.42em; line-height: 1.25; letter-spacing: -.025em; }
3520
- .welcome p { max-width: 42ch; margin: 7px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
3521
- :host([has-messages]) .welcome, :host([has-messages]) .suggested-prompts { display: none; }
3522
- .suggested-prompts { display: flex; flex: 0 0 auto; flex-wrap: wrap; gap: 8px; padding: 0 20px 16px; }
3523
- .suggested-prompts:empty { display: none; }
3524
- .suggested-prompts button { padding: 7px 12px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; cursor: pointer; transition: background .2s ease, color .2s ease, transform .2s ease; }
3525
- .suggested-prompts button:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); transform: translateY(-1px); }
3526
- .messages { flex: 1 1 auto; min-height: 0; padding: 18px 20px; overflow-y: auto; overscroll-behavior: contain; scroll-behavior: smooth; }
3527
- .messages::-webkit-scrollbar { width: 6px; }
3528
- .messages::-webkit-scrollbar-thumb { background: var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; }
3529
- .message { width: fit-content; max-width: 88%; margin: 0 0 14px; padding: 0; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: transparent; white-space: pre-wrap; animation: halo-message-in .2s ease both; }
3530
- .message > span, .message > .markdown { overflow-wrap: anywhere; }
3531
- .message .avatar { float: left; width: 24px; height: 24px; margin-right: 9px; border-radius: 50%; object-fit: cover; }
3532
- .message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; line-height: 1.2; }
3533
- .message.user { display: grid; justify-items: start; gap: 3px; margin-left: auto; padding: 10px 16px 8px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); font-size: .94em; }
3534
- .message.user time { margin-top: 0; }
3535
- .markdown { white-space: normal; }
3536
- .markdown p { margin: 0 0 8px; }
3537
- .markdown p:last-child { margin-bottom: 0; }
3538
- .markdown strong, .markdown b { font-weight: 650; }
3539
- .markdown em, .markdown i { font-style: italic; }
3540
- .markdown a { color: var(--ns-assistant-link, var(--ns-assistant-default-link)); text-decoration: underline; text-underline-offset: 2px; }
3541
- .markdown a:hover { opacity: .8; }
3542
- .markdown code { padding: 2px 6px; border-radius: 5px; background: var(--ns-assistant-code, var(--ns-assistant-default-code)); font-family: var(--ns-assistant-mono-font-family, var(--ns-assistant-default-mono-font-family)); font-size: .87em; }
3543
- .markdown pre { margin: 10px 0; padding: 12px 14px; overflow-x: auto; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 10px; background: var(--ns-assistant-code, var(--ns-assistant-default-code)); white-space: pre; }
3544
- .markdown pre code { padding: 0; background: transparent; font-size: .86em; }
3545
- .markdown ul, .markdown ol { margin: 8px 0; padding-left: 22px; }
3546
- .markdown li { margin: 3px 0; }
3547
- .markdown blockquote { margin: 10px 0; padding-left: 12px; border-left: 3px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
3548
- .markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6 { margin: 14px 0 7px; line-height: 1.25; letter-spacing: -.015em; }
3549
- .markdown h1:first-child, .markdown h2:first-child, .markdown h3:first-child { margin-top: 0; }
3550
- .markdown h1 { font-size: 1.3em; } .markdown h2 { font-size: 1.18em; } .markdown h3 { font-size: 1.08em; }
3551
- .message.thinking > span { display: inline-block; color: transparent; background: linear-gradient(90deg, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 25%, var(--ns-assistant-text, var(--ns-assistant-default-text)) 50%, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 75%); background-size: 300% 100%; background-clip: text; -webkit-background-clip: text; font-style: italic; font-weight: 500; animation: halo-shimmer 2s linear infinite; }
3552
- .tool-proposal { display: grid; gap: 10px; align-items: start; margin: 8px 0 14px; padding: 12px 14px; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 14px; background: color-mix(in srgb, var(--ns-assistant-input, var(--ns-assistant-default-input)) 78%, transparent); animation: halo-message-in .2s ease both; }
3553
- .tool-proposal > strong { font-weight: 650; overflow-wrap: anywhere; }
3554
- .proposal-arguments { display: grid; grid-template-columns: minmax(90px, auto) minmax(0, 1fr); gap: 4px 10px; margin: 0; font-size: .9em; }
3555
- .proposal-arguments dt { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
3556
- .proposal-arguments dd { margin: 0; overflow-wrap: anywhere; }
3557
- .proposal-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: end; }
3558
- .tool-proposal button { padding: 7px 11px; border: 0; border-radius: 999px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); cursor: pointer; }
3559
- .tool-proposal button:first-of-type { color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
3560
- .tool-proposal button:disabled { opacity: .55; cursor: not-allowed; }
3561
- .input-request form { display: grid; gap: 10px; align-items: stretch; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
3562
- .input-request form:focus-within { box-shadow: none; }
3563
- .input-request label { display: grid; gap: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .9em; }
3564
- .input-request input, .input-request select { width: 100%; padding: 8px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); outline: 0; font: inherit; }
3565
- .input-request select[multiple] { min-height: 88px; }
3566
- .input-request input[type="checkbox"] { width: auto; justify-self: start; accent-color: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
3567
- .input-request input:focus-visible, .input-request select:focus-visible { border-color: var(--ns-assistant-focus, var(--ns-assistant-default-focus)); box-shadow: 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
3568
- .input-request .proposal-actions { margin-top: 2px; }
3569
- form { display: flex; flex: 0 0 auto; gap: 8px; align-items: center; min-height: 48px; margin: 8px 16px 12px; padding: 8px 8px 8px 16px; border: 0; border-radius: 999px; background: var(--ns-assistant-input, var(--ns-assistant-default-input)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 60%, transparent); transition: box-shadow .15s ease; }
3570
- form:focus-within { box-shadow: inset 0 0 0 1px var(--ns-assistant-focus, var(--ns-assistant-default-focus)), 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
3571
- textarea { flex: 1; min-height: 24px; max-height: 120px; resize: none; padding: 0; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 0; border-radius: 0; outline: 0; box-shadow: none; appearance: none; -webkit-appearance: none; font: inherit; font-size: 16px; line-height: 24px; }
3572
- textarea::placeholder { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
3573
- textarea:focus, textarea:focus-visible { outline: none; box-shadow: none; }
3574
- button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }
3575
- .send { position: relative; display: block; width: 32px; height: 32px; flex: 0 0 32px; padding: 0; overflow: hidden; color: transparent; background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); font-size: 0; line-height: 0; transition: transform .15s ease, background .15s ease; }
3576
- .send::before { content: ''; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px; background: var(--ns-assistant-text, var(--ns-assistant-default-text)); transform: translate(-50%, -50%); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
3577
- .send:hover { transform: scale(1.05); background: var(--ns-assistant-hover, var(--ns-assistant-default-hover)); }
3578
- .send:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
3579
- .legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 9px; font-size: .75em; }
3580
- .legal:empty { display: none; }
3581
- .legal a { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); text-underline-offset: 2px; }
3582
- ::slotted([slot="conversation-footer"]) { display: block; padding: 0 16px 12px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: 11px; text-align: center; }
3583
- @keyframes halo-panel-in { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
3584
- @keyframes halo-message-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
3585
- @keyframes halo-shimmer { from { background-position: 100% center; } to { background-position: 0 center; } }
3586
- :host([data-density="compact"]) .welcome { padding: 20px 18px 12px; }
3587
- @media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border: 0; border-radius: 0; } }
3588
- @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } .messages { scroll-behavior: auto; } }
3589
- @media (forced-colors: active) { .message.thinking > span { color: CanvasText; background: none; } }
3590
- @media (max-width: 560px) { :host([data-mode="floating"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }
3591
- </style>`;
3592
-
3593
- // src/presentation.ts
3594
- function syncAssistantPresentation(host, root, appearance, mode, sessionState) {
3595
- const presentation = appearance.presentation;
3596
- host.dataset.panelSurface = presentation.panel.surface;
3597
- host.dataset.panelElevation = presentation.panel.elevation;
3598
- host.dataset.panelBorder = presentation.panel.border;
3599
- host.dataset.launcherEffect = presentation.launcher.effect;
3600
- host.dataset.messageUserStyle = presentation.messages.userStyle;
3601
- host.dataset.messageAssistantStyle = presentation.messages.assistantStyle;
3602
- host.dataset.sessionState = sessionState;
3603
- const radius = presentation.panel.radius;
3604
- if (radius === void 0) {
3605
- host.style.removeProperty("--ns-assistant-presentation-panel-radius");
3606
- } else {
3607
- host.style.setProperty("--ns-assistant-presentation-panel-radius", `${radius}px`);
3608
- }
3609
- host.style.setProperty(
3610
- "--ns-assistant-presentation-launcher-size",
3611
- presentation.launcher.size === "lg" ? "56px" : "48px"
3612
- );
3613
- host.style.setProperty(
3614
- "--ns-assistant-presentation-panel-background",
3615
- presentation.panel.surface === "solid" ? "var(--ns-assistant-panel, var(--ns-assistant-default-panel))" : "color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 88%, transparent)"
3616
- );
3617
- host.style.setProperty(
3618
- "--ns-assistant-presentation-shadow",
3619
- panelShadow(presentation.panel.elevation)
3620
- );
3621
- host.style.setProperty(
3622
- "--ns-assistant-presentation-border",
3623
- panelBorder(presentation.panel.border)
3624
- );
3625
- replaceFallback(root, "launcher-icon", [launcherVisual(appearance, mode, sessionState)]);
3626
- const accessibleStatus = root.querySelector("[data-session-status]");
3627
- if (accessibleStatus) {
3628
- accessibleStatus.hidden = presentation.launcher.status !== "session";
3629
- accessibleStatus.textContent = sessionStateLabel(appearance, sessionState);
3630
- }
3631
- replaceFallback(root, "header-leading", headerLeading(appearance, mode));
3632
- replaceFallback(root, "header-actions", headerBadge(appearance));
3633
- replaceFallback(root, "empty-state", [emptyState(appearance)]);
3634
- replaceFallback(root, "composer-leading", composerLeading(appearance, mode));
3635
- replaceFallback(root, "conversation-footer", []);
3636
- const form = root.querySelector("form");
3637
- if (form) form.dataset.shape = presentation.composer.shape;
3638
- const send = root.querySelector(".send");
3639
- if (send) send.dataset.icon = presentation.composer.sendIcon;
3640
- }
3641
- function syncAssistantSessionVisualState(host, root, state, appearance) {
3642
- host.dataset.sessionState = state;
3643
- root?.querySelectorAll("[data-session-indicator]").forEach((indicator) => {
3644
- indicator.dataset.state = state;
3645
- });
3646
- root?.querySelectorAll("[data-session-status]").forEach((status) => {
3647
- status.textContent = sessionStateLabel(appearance, state);
3648
- });
3649
- }
3650
- function panelShadow(elevation) {
3651
- if (elevation === "dramatic") {
3652
- return "0 34px 100px color-mix(in srgb, var(--ns-assistant-overlay, var(--ns-assistant-default-overlay)) 72%, transparent)";
3653
- }
3654
- return "var(--ns-assistant-default-shadow)";
3655
- }
3656
- function panelBorder(border) {
3657
- if (border === "strong") {
3658
- return "1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider))";
3659
- }
3660
- return "1px solid color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 74%, transparent)";
3661
- }
3662
- function launcherVisual(appearance, mode, sessionState) {
3663
- const launcher = appearance.presentation.launcher;
3664
- const visual = document.createElement("span");
3665
- visual.className = "launcher-visual";
3666
- visual.setAttribute("aria-hidden", "true");
3667
- visual.append(icon(launcher.icon, appearance, mode, "launcher-glyph"));
3668
- if (launcher.status === "session") {
3669
- const status = document.createElement("span");
3670
- status.className = "launcher-status";
3671
- status.dataset.sessionIndicator = "";
3672
- status.dataset.state = sessionState;
3673
- visual.append(status);
3674
- }
3675
- return visual;
3676
- }
3677
- function sessionStateLabel(appearance, state) {
3678
- if (state === "loading") return appearance.labels.sessionLoading;
3679
- if (state === "ready") return appearance.labels.sessionReady;
3680
- if (state === "error") return appearance.labels.sessionError;
3681
- return appearance.labels.sessionIdle;
3682
- }
3683
- function headerLeading(appearance, mode) {
3684
- const variant = appearance.presentation.header.mark;
3685
- if (variant === "none") return [];
3686
- const mark = document.createElement("span");
3687
- mark.className = "header-mark";
3688
- mark.dataset.variant = variant;
3689
- mark.setAttribute("aria-hidden", "true");
3690
- if (variant === "brand-mark") {
3691
- mark.append(icon("brand-mark", appearance, mode, "header-mark-glyph"));
3692
- } else {
3693
- const core = document.createElement("span");
3694
- core.className = "header-mark-core";
3695
- mark.append(core);
3696
- }
3697
- return [mark];
3698
- }
3699
- function headerBadge(appearance) {
3700
- const config = appearance.presentation.header;
3701
- if (!config.badge) return [];
3702
- const group = document.createElement("div");
3703
- group.className = "header-actions";
3704
- const badge = document.createElement("span");
3705
- badge.className = "header-badge";
3706
- badge.dataset.tone = config.badge.tone;
3707
- if (config.badge.indicator) badge.append(toneIndicator(config.badge.tone));
3708
- const text2 = document.createElement("span");
3709
- text2.textContent = config.badge.text;
3710
- badge.append(text2);
3711
- group.append(badge);
3712
- return [group];
3713
- }
3714
- function emptyState(appearance) {
3715
- const section = document.createElement("section");
3716
- section.className = "empty-state";
3717
- const heading = document.createElement("h2");
3718
- heading.textContent = appearance.labels.welcomeHeading;
3719
- section.append(heading);
3720
- const description = appearance.labels.welcomeMessage;
3721
- if (description) {
3722
- const paragraph = document.createElement("p");
3723
- paragraph.textContent = description;
3724
- section.append(paragraph);
3725
- }
3726
- return section;
3727
- }
3728
- function composerLeading(appearance, mode) {
3729
- const leading = appearance.presentation.composer.leadingIcon;
3730
- if (leading === "none") return [];
3731
- const wrapper = document.createElement("span");
3732
- wrapper.className = "composer-leading";
3733
- wrapper.dataset.icon = leading;
3734
- wrapper.setAttribute("aria-hidden", "true");
3735
- wrapper.append(icon(leading, appearance, mode, "composer-leading-glyph"));
3736
- return [wrapper];
3737
- }
3738
- function toneIndicator(tone) {
3739
- const indicator = document.createElement("i");
3740
- indicator.className = "tone-indicator";
3741
- indicator.dataset.tone = tone;
3742
- indicator.setAttribute("aria-hidden", "true");
3743
- return indicator;
3744
- }
3745
- function icon(kind, appearance, mode, className) {
3746
- const mark = appearance.brand.mark[mode];
3747
- if (kind === "brand-mark" && mark) {
3748
- const image = document.createElement("img");
3749
- image.className = className;
3750
- image.src = mark;
3751
- image.alt = "";
3752
- return image;
3753
- }
3754
- const glyph = document.createElement("span");
3755
- glyph.className = className;
3756
- glyph.dataset.icon = kind === "brand-mark" ? "sparkles" : kind;
3757
- glyph.setAttribute("aria-hidden", "true");
3758
- return glyph;
3759
- }
3760
- function replaceFallback(root, slotName, nodes) {
3761
- const slot = root.querySelector(`slot[name="${slotName}"]`);
3762
- slot?.replaceChildren(...nodes);
3763
- }
3764
-
3765
- // src/presentation-styles.ts
3766
- var presentationStyles = `<style>
3767
- :host([data-mode="floating"]) {
3768
- bottom: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
3769
- right: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
3770
- }
3771
- :host([data-mode="floating"][data-position="bottom-left"]) {
3772
- right: auto;
3773
- left: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
3774
- }
3775
- .panel {
3776
- background: var(--ns-assistant-panel-background, var(--ns-assistant-presentation-panel-background));
3777
- border: var(--ns-assistant-panel-border, var(--ns-assistant-presentation-border));
3778
- border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-presentation-panel-radius, var(--ns-assistant-default-panel-radius)));
3779
- box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-presentation-shadow));
3780
- }
3781
- :host([data-panel-surface="solid"]) .panel {
3782
- backdrop-filter: none;
3783
- -webkit-backdrop-filter: none;
3784
- }
3785
-
3786
- .launcher {
3787
- position: relative;
3788
- width: var(--ns-assistant-launcher-size, var(--ns-assistant-presentation-launcher-size));
3789
- height: var(--ns-assistant-launcher-size, var(--ns-assistant-presentation-launcher-size));
3790
- border-radius: var(--ns-assistant-launcher-radius, var(--ns-assistant-default-launcher-radius));
3791
- isolation: isolate;
3792
- }
3793
- :host([data-launcher-effect="pulse"]) .launcher {
3794
- animation: assistant-launcher-pulse 2s ease-in-out infinite;
3795
- }
3796
- .launcher-visual {
3797
- position: relative;
3798
- display: grid;
3799
- width: 100%;
3800
- height: 100%;
3801
- place-items: center;
3802
- border-radius: inherit;
3803
- }
3804
- .launcher-glyph, .composer-leading-glyph {
3805
- display: block;
3806
- width: 18px;
3807
- height: 18px;
3808
- background: currentColor;
3809
- -webkit-mask-position: center;
3810
- -webkit-mask-repeat: no-repeat;
3811
- -webkit-mask-size: contain;
3812
- mask-position: center;
3813
- mask-repeat: no-repeat;
3814
- mask-size: contain;
3815
- }
3816
- [data-icon="sparkles"] {
3817
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 3 1.7 5.3L19 10l-5.3 1.7L12 17l-1.7-5.3L5 10l5.3-1.7L12 3Zm6 11 .8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8L18 14Z'/%3E%3C/svg%3E");
3818
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 3 1.7 5.3L19 10l-5.3 1.7L12 17l-1.7-5.3L5 10l5.3-1.7L12 3Zm6 11 .8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8L18 14Z'/%3E%3C/svg%3E");
3819
- }
3820
- [data-icon="chat"] {
3821
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 4h16v12H9l-5 4V4Zm4 5h8v2H8V9Z'/%3E%3C/svg%3E");
3822
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 4h16v12H9l-5 4V4Zm4 5h8v2H8V9Z'/%3E%3C/svg%3E");
3823
- }
3824
- [data-icon="none"] { display: none; }
3825
- .launcher-glyph:is(img), .composer-leading-glyph:is(img), .header-mark-glyph:is(img) {
3826
- background: none;
3827
- object-fit: contain;
3828
- -webkit-mask: none;
3829
- mask: none;
3830
- }
3831
- .launcher-status {
3832
- position: absolute;
3833
- right: 1px;
3834
- bottom: 1px;
3835
- width: 10px;
3836
- height: 10px;
3837
- border: 2px solid var(--ns-assistant-panel, var(--ns-assistant-default-panel));
3838
- border-radius: 50%;
3839
- background: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text));
3840
- }
3841
- .launcher-status[data-state="loading"] {
3842
- background: var(--ns-assistant-warning, var(--ns-assistant-default-warning));
3843
- animation: assistant-launcher-pulse 1.2s ease-in-out infinite;
3844
- }
3845
- .launcher-status[data-state="ready"] {
3846
- background: var(--ns-assistant-success, var(--ns-assistant-default-success));
3847
- box-shadow: 0 0 9px color-mix(in srgb, var(--ns-assistant-success, var(--ns-assistant-default-success)) 70%, transparent);
3848
- }
3849
- .launcher-status[data-state="error"] {
3850
- background: var(--ns-assistant-danger, var(--ns-assistant-default-danger));
3851
- }
3852
-
3853
- .header-mark {
3854
- position: relative;
3855
- display: grid;
3856
- width: 26px;
3857
- height: 26px;
3858
- flex: 0 0 26px;
3859
- place-items: center;
3860
- color: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
3861
- }
3862
- .header-mark[data-variant="status"] .header-mark-core {
3863
- width: 9px;
3864
- height: 9px;
3865
- border-radius: 50%;
3866
- background: var(--ns-assistant-success, var(--ns-assistant-default-success));
3867
- box-shadow: 0 0 0 5px color-mix(in srgb, var(--ns-assistant-success, var(--ns-assistant-default-success)) 16%, transparent);
3868
- }
3869
- .header-mark-glyph {
3870
- width: 24px;
3871
- height: 24px;
3872
- object-fit: contain;
3873
- }
3874
- .header-actions {
3875
- display: flex;
3876
- align-items: center;
3877
- }
3878
- .header-badge {
3879
- display: inline-flex;
3880
- align-items: center;
3881
- gap: 6px;
3882
- min-height: 28px;
3883
- padding: 0 10px;
3884
- border: 1px solid color-mix(in srgb, var(--presentation-tone, var(--ns-assistant-accent, var(--ns-assistant-default-accent))) 22%, transparent);
3885
- border-radius: 999px;
3886
- color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text));
3887
- background: color-mix(in srgb, var(--presentation-tone, var(--ns-assistant-accent, var(--ns-assistant-default-accent))) 7%, transparent);
3888
- font-family: var(--ns-assistant-mono-font-family, var(--ns-assistant-default-mono-font-family));
3889
- font-size: 9px;
3890
- font-weight: 650;
3891
- letter-spacing: .11em;
3892
- text-transform: uppercase;
3893
- }
3894
- [data-tone="success"] { --presentation-tone: var(--ns-assistant-success, var(--ns-assistant-default-success)); }
3895
- [data-tone="warning"] { --presentation-tone: var(--ns-assistant-warning, var(--ns-assistant-default-warning)); }
3896
- [data-tone="danger"] { --presentation-tone: var(--ns-assistant-danger, var(--ns-assistant-default-danger)); }
3897
- [data-tone="neutral"] { --presentation-tone: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
3898
- .tone-indicator {
3899
- display: inline-block;
3900
- width: 6px;
3901
- height: 6px;
3902
- flex: 0 0 6px;
3903
- border-radius: 50%;
3904
- background: var(--presentation-tone);
3905
- box-shadow: 0 0 8px color-mix(in srgb, var(--presentation-tone) 72%, transparent);
3906
- }
3907
-
3908
- .empty-state { min-width: 0; }
3909
- .composer-leading {
3910
- display: grid;
3911
- width: 20px;
3912
- height: 20px;
3913
- flex: 0 0 20px;
3914
- place-items: center;
3915
- color: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
3916
- }
3917
- .composer-leading-glyph { width: 15px; height: 15px; }
3918
- form[data-shape="rounded"] {
3919
- border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius));
3920
- }
3921
- form[data-shape="pill"] { border-radius: 999px; }
3922
- .send[data-icon="paper-plane"]::before {
3923
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m3 4 18 8-18 8 3-7 9-1-9-1-3-7Z'/%3E%3C/svg%3E");
3924
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m3 4 18 8-18 8 3-7 9-1-9-1-3-7Z'/%3E%3C/svg%3E");
3925
- }
3926
-
3927
- :host([data-message-user-style="accent"]) .message.user {
3928
- color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text));
3929
- background: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
3930
- }
3931
- :host([data-message-user-style="accent"]) .message.user time {
3932
- color: color-mix(in srgb, var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)) 72%, transparent);
3933
- }
3934
- :host([data-message-assistant-style="bubble"]) .message.assistant {
3935
- padding: 10px 14px;
3936
- background: var(--ns-assistant-input, var(--ns-assistant-default-input));
3937
- }
3938
-
3939
- @keyframes assistant-launcher-pulse { 50% { opacity: .55; transform: scale(.9); } }
3940
-
3941
- @media (max-width: 640px) {
3942
- .header-badge { display: none; }
3943
- }
3944
- @media (prefers-reduced-motion: reduce) {
3945
- .launcher, .launcher-status { animation: none !important; }
3946
- }
3947
- </style>`;
3948
-
3949
- // src/element.ts
3950
- var ASSISTANT_TAG_NAME = "noodle-assistant";
3951
- var HTMLElementBase = globalThis.HTMLElement ?? class {
3952
- };
3953
- var NoodleAssistantElement = class extends HTMLElementBase {
3954
- static observedAttributes = ["open", "theme"];
3955
- #appearance = resolveAppearance();
3956
- #client;
3957
- #clientEndpoint = "";
3958
- #unsubscribeClient;
3959
- #sessionBootstrap;
3960
- #conversationGeneration = 0;
3961
- #messages;
3962
- #thinking;
3963
- #media;
3964
- #context;
3965
- #modelContext;
3966
- #pendingUserEcho;
3967
- #sessionState = "idle";
3968
- #startOpenApplied = false;
3969
- sessionEndpoint = "";
3970
- #events = new AssistantElementEventController({
3971
- element: this,
3972
- messages: () => this.#messages,
3973
- appendMessage: (role, text2) => {
3974
- if (role === "user" && text2 === this.#pendingUserEcho) {
3975
- this.#pendingUserEcho = void 0;
3976
- return void 0;
3977
- }
3978
- return this.#appendMessage(role, text2);
3979
- },
3980
- applyConfiguration: (configuration) => {
3981
- this.#appearance = resolveAppearance(configuration);
3982
- this.#syncAppearance();
3983
- this.#applyStartOpenPolicy();
3984
- },
3985
- labels: () => ({
3986
- confirm: this.#appearance.labels.confirm,
3987
- cancel: this.#appearance.labels.cancel
3988
- }),
3989
- respond: (id, response) => this.respond(id, response),
3990
- dispatchError: (detail) => this.#dispatchError(detail)
3991
- });
3992
- connectedCallback() {
3993
- if (!this.shadowRoot) this.attachShadow({ mode: "open" });
3994
- if (!this.sessionEndpoint) this.sessionEndpoint = this.getAttribute("session-endpoint") ?? "";
3995
- this.#media = globalThis.matchMedia?.("(prefers-color-scheme: dark)");
3996
- this.#media?.addEventListener("change", this.#handleSystemTheme);
3997
- document.addEventListener("keydown", this.#handleDocumentKeydown);
3998
- document.addEventListener("pointerdown", this.#handleDocumentPointerDown);
3999
- if (this.#appearance.behavior.startOpen) this.#applyStartOpenPolicy();
4000
- this.#render();
4001
- this.dispatchEvent(new CustomEvent("assistant-ready"));
4002
- this.#primeSession();
4003
- }
4004
- disconnectedCallback() {
4005
- this.#conversationGeneration += 1;
4006
- this.#client?.abort();
4007
- this.#unsubscribeClient?.();
4008
- this.#client = void 0;
4009
- this.#clientEndpoint = "";
4010
- this.#unsubscribeClient = void 0;
4011
- this.#sessionBootstrap = void 0;
4012
- this.#setBusy(false);
4013
- this.#media?.removeEventListener("change", this.#handleSystemTheme);
4014
- document.removeEventListener("keydown", this.#handleDocumentKeydown);
4015
- document.removeEventListener("pointerdown", this.#handleDocumentPointerDown);
4016
- }
4017
- attributeChangedCallback(name) {
4018
- if (name === "theme") this.#applyTheme();
4019
- if (name === "open") this.#syncOpenState();
4020
- }
4021
- open() {
4022
- this.setAttribute("open", "");
4023
- this.dispatchEvent(new CustomEvent("assistant-open"));
4024
- }
4025
- close() {
4026
- this.removeAttribute("open");
4027
- this.dispatchEvent(new CustomEvent("assistant-close"));
4028
- }
4029
- toggle() {
4030
- this.hasAttribute("open") ? this.close() : this.open();
4031
- }
4032
- focusComposer() {
4033
- this.shadowRoot?.querySelector("textarea")?.focus();
4034
- }
4035
- resetSession() {
4036
- this.#conversationGeneration += 1;
4037
- this.#client?.abort();
4038
- this.#unsubscribeClient?.();
4039
- this.#client = void 0;
4040
- this.#clientEndpoint = "";
4041
- this.#unsubscribeClient = void 0;
4042
- this.#sessionBootstrap = void 0;
4043
- this.#events.resetConversation();
4044
- this.#pendingUserEcho = void 0;
4045
- this.removeAttribute("has-messages");
4046
- this.#setBusy(false);
4047
- this.#setSessionState("idle");
4048
- }
4049
- updateContext(context) {
4050
- this.#context = { ...context };
4051
- if (this.#client) {
4052
- this.#client.updateContext(this.#context);
4053
- } else {
4054
- this.dispatchEvent(
4055
- new CustomEvent("assistant-context-changed", { detail: { context: this.#context } })
4056
- );
4057
- }
4058
- }
4059
- /** Replace the compact renderer summary attached to subsequent message turns. */
4060
- updateModelContext(update) {
4061
- this.#modelContext = copyAssistantModelContext(update);
4062
- if (this.#client) {
4063
- this.#client.updateModelContext(this.#modelContext);
4064
- } else {
4065
- this.dispatchEvent(
4066
- new CustomEvent("assistant-model-context-changed", {
4067
- detail: { modelContext: this.#modelContext }
4068
- })
4069
- );
4070
- }
4071
- }
4072
- async sendMessage(text2) {
4073
- const message = text2.trim();
4074
- if (!message) return;
4075
- const generation = this.#conversationGeneration;
4076
- this.#pendingUserEcho = message;
4077
- this.#appendMessage("user", message);
4078
- this.#setBusy(true);
4079
- if (this.#sessionState !== "ready") this.#setSessionState("loading");
4080
- try {
4081
- await this.#sessionBootstrap;
4082
- if (generation !== this.#conversationGeneration) return;
4083
- await this.#ensureClient().sendMessage(message);
4084
- } catch (error) {
4085
- if (generation !== this.#conversationGeneration) return;
4086
- this.#dispatchClientError(error, "turn_failed");
4087
- throw error;
4088
- } finally {
4089
- if (this.#pendingUserEcho === message) this.#pendingUserEcho = void 0;
4090
- if (generation === this.#conversationGeneration) this.#setBusy(false);
4091
- }
4092
- }
4093
- /**
4094
- * Every listener the element attaches to its own DOM must go through this guard: internal UI
4095
- * failures surface as `assistant-error` events (already dispatched by the failing path) and must
4096
- * never escape as unhandled rejections into the embedding page. Programmatic callers use
4097
- * `sendMessage`/`confirmTool` directly and keep the rejection.
4098
- */
4099
- #sendGuarded(text2) {
4100
- void this.sendMessage(text2).catch(() => {
4101
- });
4102
- }
4103
- async confirmTool(id) {
4104
- await this.respond(id, { action: "accept" });
4105
- }
4106
- async respond(id, response) {
4107
- const generation = this.#conversationGeneration;
4108
- this.#setBusy(true);
4109
- try {
4110
- await this.#ensureClient().respond(id, response);
4111
- } catch (error) {
4112
- if (generation !== this.#conversationGeneration) return;
4113
- this.#dispatchClientError(error, "confirmation_failed");
4114
- throw error;
4115
- } finally {
4116
- if (generation === this.#conversationGeneration) this.#setBusy(false);
4117
- }
4118
- }
4119
- #handleSystemTheme = () => this.#applyTheme();
4120
- #handleDocumentKeydown = (event) => {
4121
- if (event.key === "Escape" && this.hasAttribute("open") && this.#appearance.behavior.closeOnEscape) {
4122
- this.#closeAndRestoreFocus();
4123
- }
4124
- };
4125
- #handleDocumentPointerDown = (event) => {
4126
- if (this.hasAttribute("open") && this.#appearance.behavior.closeOnOutsideClick && !event.composedPath().includes(this)) {
4127
- this.close();
4128
- }
4129
- };
4130
- #ensureClient() {
4131
- if (this.#client && this.#clientEndpoint === this.sessionEndpoint) return this.#client;
4132
- this.#client?.abort();
4133
- this.#unsubscribeClient?.();
4134
- this.#sessionBootstrap = void 0;
4135
- const client = createAssistantClient({
4136
- sessionEndpoint: this.sessionEndpoint,
4137
- ...this.#context ? { context: this.#context } : {},
4138
- clientContext: browserClientContext,
4139
- ...this.#modelContext ? { modelContext: this.#modelContext } : {}
4140
- });
4141
- this.#client = client;
4142
- this.#clientEndpoint = this.sessionEndpoint;
4143
- this.#unsubscribeClient = client.subscribe((event) => {
4144
- if (this.#client === client) this.#handleClientEvent(event);
4145
- });
4146
- return client;
4147
- }
4148
- #primeSession() {
4149
- if (!this.sessionEndpoint) return;
4150
- const client = this.#ensureClient();
4151
- const generation = this.#conversationGeneration;
4152
- this.#setSessionState("loading");
4153
- const bootstrap = client.connect().catch((error) => {
4154
- if (generation !== this.#conversationGeneration || this.#client !== client) return;
4155
- this.#dispatchClientError(error, "session_failed");
4156
- }).finally(() => {
4157
- if (this.#sessionBootstrap === bootstrap) this.#sessionBootstrap = void 0;
4158
- });
4159
- this.#sessionBootstrap = bootstrap;
4160
- }
4161
- #handleClientEvent(event) {
4162
- this.#events.handle(event);
4163
- if (event.event === "session_started") this.#setSessionState("ready");
4164
- if (event.event === "session_expired" || event.event === "session_reset") {
4165
- this.#setSessionState("idle");
4166
- }
4167
- if (event.event === "tool_proposed" || event.event === "interaction_proposed" || event.event === "input_requested") {
4168
- this.#removeThinking();
4169
- this.setAttribute("has-messages", "");
4170
- this.#scrollToBottom();
4171
- }
4172
- if (event.event === "content" || event.event === "message_completed" || event.event === "interaction_completed" || event.event === "error") {
4173
- this.#removeThinking();
4174
- this.#scrollToBottom();
4175
- }
4176
- }
4177
- #setBusy(busy) {
4178
- this.toggleAttribute("busy", busy);
4179
- const textarea = this.shadowRoot?.querySelector("textarea");
4180
- const send = this.shadowRoot?.querySelector(".send");
4181
- if (textarea) textarea.disabled = busy;
4182
- if (send) send.disabled = busy;
4183
- if (!busy) {
4184
- this.#removeThinking();
4185
- return;
4186
- }
4187
- if (!this.#messages || this.#thinking) return;
4188
- const thinking = document.createElement("div");
4189
- thinking.className = "message assistant thinking";
4190
- const label = document.createElement("span");
4191
- label.textContent = this.#appearance.labels.thinking;
4192
- thinking.append(label);
4193
- this.#messages.append(thinking);
4194
- this.#thinking = thinking;
4195
- this.#scrollToBottom();
4196
- }
4197
- #removeThinking() {
4198
- this.#thinking?.remove();
4199
- this.#thinking = void 0;
4200
- }
4201
- #appendMessage(role, text2) {
4202
- if (!this.#messages) return void 0;
4203
- const message = document.createElement("div");
4204
- message.className = `message ${role}`;
4205
- if (role === "assistant" && this.#appearance.behavior.showAvatars && this.#appearance.brand.avatar[this.#resolvedMode()]) {
4206
- const avatar = document.createElement("img");
4207
- avatar.className = "avatar";
4208
- avatar.src = this.#appearance.brand.avatar[this.#resolvedMode()] ?? "";
4209
- avatar.alt = "";
4210
- message.append(avatar);
4211
- }
4212
- const body = document.createElement(role === "assistant" ? "div" : "span");
4213
- if (role === "assistant") {
4214
- body.className = "markdown";
4215
- body.innerHTML = renderMarkdown(text2);
4216
- } else {
4217
- body.textContent = text2;
4218
- }
4219
- message.append(body);
4220
- if (this.#appearance.behavior.showTimestamps) {
4221
- const timestamp = document.createElement("time");
4222
- timestamp.dateTime = (/* @__PURE__ */ new Date()).toISOString();
4223
- timestamp.textContent = new Intl.DateTimeFormat(this.#appearance.locale, {
4224
- hour: "numeric",
4225
- minute: "2-digit"
4226
- }).format(/* @__PURE__ */ new Date());
4227
- message.append(timestamp);
4228
- }
4229
- this.#messages.append(message);
4230
- this.setAttribute("has-messages", "");
4231
- this.#scrollToBottom();
4232
- return body;
4233
- }
4234
- #scrollToBottom() {
4235
- if (this.#messages) this.#messages.scrollTop = this.#messages.scrollHeight;
4236
- }
4237
- #dispatchError(detail) {
4238
- this.dispatchEvent(new CustomEvent("assistant-error", { detail }));
4239
- }
4240
- #dispatchClientError(error, fallbackCode) {
4241
- if (error instanceof AssistantClientError && error.detail.code === "session_failed") {
4242
- this.#setSessionState("error");
4243
- }
4244
- this.#dispatchError(
4245
- error instanceof AssistantClientError ? error.detail : { code: fallbackCode, retryable: false }
4246
- );
4247
- }
4248
- #resolvedMode() {
4249
- const configured = this.getAttribute("theme") ?? this.#appearance.theme.defaultMode;
4250
- return configured === "auto" ? this.#media?.matches ? "dark" : "light" : configured;
4251
- }
4252
- #applyTheme() {
4253
- const mode = this.#resolvedMode();
4254
- this.setAttribute("data-theme", mode);
4255
- const tokens = this.#appearance.theme[mode];
4256
- for (const [name, value] of Object.entries(tokens)) {
4257
- this.style.setProperty(
4258
- `--ns-assistant-default-${camelToKebab(name)}`,
4259
- tokenValue(name, value)
4260
- );
4261
- }
4262
- this.style.setProperty(
4263
- "--ns-assistant-default-panel-width",
4264
- `${this.#appearance.layout.panelWidth}px`
4265
- );
4266
- this.style.setProperty(
4267
- "--ns-assistant-default-min-height",
4268
- `${this.#appearance.layout.panelMinHeight}px`
4269
- );
4270
- this.style.setProperty(
4271
- "--ns-assistant-default-max-height",
4272
- `${this.#appearance.layout.panelMaxHeight}px`
4273
- );
4274
- this.style.setProperty(
4275
- "--ns-assistant-default-z-index",
4276
- String(this.#appearance.layout.zIndex)
4277
- );
4278
- this.style.setProperty(
4279
- "--ns-assistant-default-edge-offset",
4280
- `${this.#appearance.layout.edgeOffset}px`
4281
- );
4282
- const logo = this.shadowRoot?.querySelector(".brand-logo");
4283
- const logoUrl = this.#appearance.brand.logo[mode];
4284
- if (logo) {
4285
- logo.hidden = !logoUrl;
4286
- if (logoUrl) logo.src = logoUrl;
4287
- }
4288
- if (this.shadowRoot) {
4289
- syncAssistantPresentation(this, this.shadowRoot, this.#appearance, mode, this.#sessionState);
4290
- }
4291
- }
4292
- #setSessionState(state) {
4293
- this.#sessionState = state;
4294
- syncAssistantSessionVisualState(this, this.shadowRoot, state, this.#appearance);
4295
- }
4296
- #syncOpenState() {
4297
- this.shadowRoot?.querySelector(".launcher")?.setAttribute("aria-expanded", String(this.hasAttribute("open")));
4298
- }
4299
- #closeAndRestoreFocus() {
4300
- this.close();
4301
- this.shadowRoot?.querySelector(".launcher")?.focus();
4302
- }
4303
- #applyStartOpenPolicy() {
4304
- if (this.#startOpenApplied) return;
4305
- this.#startOpenApplied = true;
4306
- if (this.#appearance.behavior.startOpen) this.setAttribute("open", "");
4307
- }
4308
- #syncAppearance() {
4309
- if (!this.shadowRoot) return;
4310
- const appearance = this.#appearance;
4311
- this.setAttribute("aria-label", appearance.brand.name);
4312
- this.setAttribute("lang", appearance.locale);
4313
- this.setAttribute("dir", appearance.direction);
4314
- this.dataset.mode = appearance.layout.mode;
4315
- this.dataset.position = appearance.layout.position;
4316
- this.dataset.density = appearance.layout.density;
4317
- this.toggleAttribute("mobile-fullscreen", appearance.layout.mobileFullscreen);
4318
- queryRequired(this.shadowRoot, ".panel").setAttribute(
4319
- "aria-label",
4320
- appearance.brand.name
4321
- );
4322
- queryRequired(this.shadowRoot, "header strong").textContent = appearance.brand.name;
4323
- const textarea = queryRequired(this.shadowRoot, "textarea");
4324
- textarea.placeholder = appearance.labels.composerPlaceholder;
4325
- textarea.setAttribute("aria-label", appearance.labels.composerPlaceholder);
4326
- queryRequired(this.shadowRoot, ".send").textContent = appearance.labels.send;
4327
- queryRequired(this.shadowRoot, ".launcher").setAttribute(
4328
- "aria-label",
4329
- appearance.labels.open
4330
- );
4331
- queryRequired(this.shadowRoot, ".close").setAttribute(
4332
- "aria-label",
4333
- appearance.labels.close
4334
- );
4335
- const prompts = queryRequired(this.shadowRoot, ".suggested-prompts");
4336
- prompts.replaceChildren();
4337
- for (const prompt of appearance.suggestedPrompts) {
4338
- const button2 = document.createElement("button");
4339
- button2.type = "button";
4340
- button2.textContent = prompt;
4341
- button2.addEventListener("click", () => this.#sendGuarded(prompt));
4342
- prompts.append(button2);
4343
- }
4344
- queryRequired(this.shadowRoot, ".launcher").hidden = !appearance.behavior.showLauncher;
4345
- queryRequired(this.shadowRoot, "header").hidden = !appearance.behavior.showHeader;
4346
- const legal = queryRequired(this.shadowRoot, ".legal");
4347
- legal.replaceChildren();
4348
- this.#appendLegalLinks(legal);
4349
- this.#applyTheme();
4350
- }
4351
- #render() {
4352
- if (!this.shadowRoot) return;
4353
- const conversation = this.#messages ? [...this.#messages.childNodes] : [];
4354
- const appearance = this.#appearance;
4355
- this.setAttribute("role", "complementary");
4356
- this.setAttribute("aria-label", appearance.brand.name);
4357
- this.setAttribute("lang", appearance.locale);
4358
- this.setAttribute("dir", appearance.direction);
4359
- this.dataset.mode = appearance.layout.mode;
4360
- this.dataset.position = appearance.layout.position;
4361
- this.dataset.density = appearance.layout.density;
4362
- this.toggleAttribute("mobile-fullscreen", appearance.layout.mobileFullscreen);
4363
- this.shadowRoot.innerHTML = `${ASSISTANT_ELEMENT_STYLES}${presentationStyles}
4364
- <button class="launcher" type="button" aria-label="${escapeAttribute(appearance.labels.open)}" aria-controls="assistant-panel" aria-expanded="${String(this.hasAttribute("open"))}"><slot name="launcher-icon"></slot><span class="visually-hidden" data-session-status aria-live="polite" hidden></span></button>
4365
- <section class="panel" id="assistant-panel" role="dialog" aria-label="${escapeAttribute(appearance.brand.name)}">
4366
- <header><slot name="header-leading"></slot><img class="brand-logo" alt=""><strong></strong><slot name="header-actions"></slot><button class="close" type="button" aria-label="${escapeAttribute(appearance.labels.close)}">\xD7</button></header>
4367
- <div class="welcome"><slot name="empty-state"></slot></div>
4368
- <div class="suggested-prompts"></div>
4369
- <div class="messages" aria-live="polite"></div>
4370
- <form><slot name="composer-leading"></slot><textarea rows="1"></textarea><button class="send" type="submit"></button><slot name="composer-trailing"></slot></form>
4371
- <nav class="legal" aria-label="Legal"></nav>
4372
- <slot name="conversation-footer"></slot>
4373
- </section>`;
4374
- queryRequired(this.shadowRoot, "strong").textContent = appearance.brand.name;
4375
- const logo = queryRequired(this.shadowRoot, ".brand-logo");
4376
- const logoUrl = appearance.brand.logo[this.#resolvedMode()];
4377
- if (logoUrl) {
4378
- logo.src = logoUrl;
4379
- logo.alt = appearance.brand.name;
4380
- } else {
4381
- logo.hidden = true;
4382
- }
4383
- const textarea = queryRequired(this.shadowRoot, "textarea");
4384
- textarea.placeholder = appearance.labels.composerPlaceholder;
4385
- textarea.setAttribute("aria-label", appearance.labels.composerPlaceholder);
4386
- queryRequired(this.shadowRoot, ".send").textContent = appearance.labels.send;
4387
- const prompts = queryRequired(this.shadowRoot, ".suggested-prompts");
4388
- for (const prompt of appearance.suggestedPrompts) {
4389
- const button2 = document.createElement("button");
4390
- button2.type = "button";
4391
- button2.textContent = prompt;
4392
- button2.addEventListener("click", () => this.#sendGuarded(prompt));
4393
- prompts.append(button2);
4394
- }
4395
- if (!appearance.behavior.showLauncher)
4396
- queryRequired(this.shadowRoot, ".launcher").hidden = true;
4397
- if (!appearance.behavior.showHeader)
4398
- queryRequired(this.shadowRoot, "header").hidden = true;
4399
- const legal = queryRequired(this.shadowRoot, ".legal");
4400
- this.#appendLegalLinks(legal);
4401
- this.#messages = this.shadowRoot.querySelector(".messages") ?? void 0;
4402
- this.#messages?.append(...conversation);
4403
- this.#thinking = this.#messages?.querySelector(".thinking") ?? void 0;
4404
- this.shadowRoot.querySelector(".launcher")?.addEventListener("click", () => {
4405
- this.open();
4406
- this.focusComposer();
4407
- });
4408
- this.shadowRoot.querySelector(".close")?.addEventListener("click", () => this.#closeAndRestoreFocus());
4409
- const form = queryRequired(this.shadowRoot, "form");
4410
- form.addEventListener("submit", (event) => {
4411
- event.preventDefault();
4412
- const value = textarea.value;
4413
- textarea.value = "";
4414
- textarea.style.height = "auto";
4415
- this.#sendGuarded(value);
4416
- });
4417
- textarea.addEventListener("input", () => {
4418
- textarea.style.height = "auto";
4419
- textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
4420
- });
4421
- textarea.addEventListener("keydown", (event) => {
4422
- if (event.key !== "Enter" || event.shiftKey || event.isComposing) return;
4423
- event.preventDefault();
4424
- form.requestSubmit();
4425
- });
4426
- this.#applyTheme();
4427
- }
4428
- #appendLegalLinks(legal) {
4429
- for (const [label, href] of [
4430
- ["Privacy", this.#appearance.privacyUrl],
4431
- ["Terms", this.#appearance.termsUrl]
4432
- ]) {
4433
- if (!href) continue;
4434
- const link = document.createElement("a");
4435
- link.href = href;
4436
- link.target = "_blank";
4437
- link.rel = "noopener noreferrer";
4438
- link.textContent = label;
4439
- legal.append(link);
4440
- }
4441
- }
4442
- };
4443
- function registerNoodleAssistant() {
4444
- if (globalThis.customElements && !customElements.get(ASSISTANT_TAG_NAME)) {
4445
- customElements.define(ASSISTANT_TAG_NAME, NoodleAssistantElement);
4446
- }
4447
- }
4448
-
4449
- export {
4450
- ASSISTANT_TAG_NAME,
4451
- NoodleAssistantElement,
4452
- registerNoodleAssistant
4453
- };
4454
- /*! Bundled license information:
4455
-
4456
- dompurify/dist/purify.es.mjs:
4457
- (*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE *)
4458
- */
4459
- //# sourceMappingURL=chunk-QMDSNLTA.js.map