@artooi/ag-ui-web-component 0.32.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -1
- package/README.md +182 -23
- package/dist/ag-ui-web-component.bundle.js +360 -121
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +1275 -390
- package/dist/index.js.map +4 -4
- package/dist/ui/clamp_launcher.d.ts +15 -0
- package/dist/ui/clamp_launcher.d.ts.map +1 -0
- package/dist/ui/copy_payload.d.ts +30 -0
- package/dist/ui/copy_payload.d.ts.map +1 -0
- package/dist/ui/launcher_drag.d.ts +43 -0
- package/dist/ui/launcher_drag.d.ts.map +1 -0
- package/dist/ui/launcher_placement.d.ts +64 -0
- package/dist/ui/launcher_placement.d.ts.map +1 -0
- package/dist/ui/message_actions.d.ts +30 -2
- package/dist/ui/message_actions.d.ts.map +1 -1
- package/dist/ui/resize_handle.d.ts +32 -26
- package/dist/ui/resize_handle.d.ts.map +1 -1
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +12 -0
- package/src/core/ag_ui_chat.ts +480 -24
- package/src/ui/clamp_launcher.ts +20 -0
- package/src/ui/copy_payload.ts +156 -0
- package/src/ui/launcher_drag.ts +182 -0
- package/src/ui/launcher_placement.ts +143 -0
- package/src/ui/message_actions.ts +93 -19
- package/src/ui/resize_handle.ts +109 -73
- package/src/ui/styles.ts +299 -82
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -60,6 +60,10 @@ var ICON_STOP = `<svg class="glyph glyph--solid" viewBox="0 0 24 24" aria-hidden
|
|
|
60
60
|
var ICON_ATTACH = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M17 8.5V15a5 5 0 0 1-10 0V7a3 3 0 0 1 6 0v7.5a1 1 0 0 1-2 0V8.5"/></svg>`;
|
|
61
61
|
var ICON_VOICE = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4a3 3 0 0 1 3 3v5a3 3 0 0 1-6 0V7a3 3 0 0 1 3-3z"/><path d="M5 11v1a7 7 0 0 0 14 0v-1"/><path d="M12 19v3"/></svg>`;
|
|
62
62
|
var ICON_LAUNCHER = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H9l-5 4z"/></svg>`;
|
|
63
|
+
var ICON_COPY = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h8"/></svg>`;
|
|
64
|
+
var ICON_RETRY = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.5-5.8"/><path d="M20 4v4h-4"/></svg>`;
|
|
65
|
+
var ICON_THUMB_UP = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10v10H4V10z"/><path d="M7 10l4.5-7a2 2 0 0 1 3.4 2L13.5 9H19a2 2 0 0 1 2 2.3l-1.1 6.4A2 2 0 0 1 17.9 20H7"/></svg>`;
|
|
66
|
+
var ICON_THUMB_DOWN = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M17 14V4h3v10z"/><path d="M17 14l-4.5 7a2 2 0 0 1-3.4-2l1.4-4H5a2 2 0 0 1-2-2.3l1.1-6.4A2 2 0 0 1 6.1 4H17"/></svg>`;
|
|
63
67
|
var ICON_FILE = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/></svg>`;
|
|
64
68
|
var ICON_FILE_IMAGE = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="15" rx="2.5"/><circle cx="9" cy="10" r="1.5"/><path d="M4.5 17.5 9 13.5l3.5 3 3-2.5 4.5 4"/></svg>`;
|
|
65
69
|
var ICON_FILE_PDF = `<svg class="glyph" viewBox="0 0 24 24" aria-hidden="true"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><rect class="glyph--solid" x="7.5" y="13.5" width="9" height="4.5" rx="1"/></svg>`;
|
|
@@ -74,7 +78,7 @@ import { randomUUID as randomUUID5 } from "@ag-ui/client";
|
|
|
74
78
|
var PLACEHOLDER_RE = /\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
75
79
|
function fillTemplate(template, values) {
|
|
76
80
|
const missing = [];
|
|
77
|
-
const
|
|
81
|
+
const text4 = template.replace(PLACEHOLDER_RE, (token, key) => {
|
|
78
82
|
const value = values[key];
|
|
79
83
|
if (value === void 0 || value === null || value === "") {
|
|
80
84
|
if (!missing.includes(key)) {
|
|
@@ -84,7 +88,7 @@ function fillTemplate(template, values) {
|
|
|
84
88
|
}
|
|
85
89
|
return String(value);
|
|
86
90
|
});
|
|
87
|
-
return { text:
|
|
91
|
+
return { text: text4, missing };
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
// src/skills/parse_skills.ts
|
|
@@ -433,8 +437,8 @@ function createPageStateTools(binding) {
|
|
|
433
437
|
handler: () => binding.read()
|
|
434
438
|
}
|
|
435
439
|
];
|
|
436
|
-
const
|
|
437
|
-
if (
|
|
440
|
+
const write2 = binding.write;
|
|
441
|
+
if (write2 !== void 0) {
|
|
438
442
|
tools.push({
|
|
439
443
|
name: `set_${binding.name}`,
|
|
440
444
|
description: `Update the "${binding.name}" state.`,
|
|
@@ -443,7 +447,7 @@ function createPageStateTools(binding) {
|
|
|
443
447
|
[X_DESTRUCTIVE_KEY]: true,
|
|
444
448
|
[X_SUMMARY_KEY]: `Update ${binding.name}`
|
|
445
449
|
},
|
|
446
|
-
handler: (args) =>
|
|
450
|
+
handler: (args) => write2(args)
|
|
447
451
|
});
|
|
448
452
|
}
|
|
449
453
|
return tools;
|
|
@@ -780,7 +784,7 @@ function attachCopyButtons(root, strings) {
|
|
|
780
784
|
}
|
|
781
785
|
}
|
|
782
786
|
function button(code, strings) {
|
|
783
|
-
const
|
|
787
|
+
const text4 = code.textContent;
|
|
784
788
|
const copy = document.createElement("button");
|
|
785
789
|
copy.type = "button";
|
|
786
790
|
copy.className = "code-copy";
|
|
@@ -789,19 +793,19 @@ function button(code, strings) {
|
|
|
789
793
|
copy.title = strings.copyCode;
|
|
790
794
|
copy.setAttribute("aria-label", strings.copyCode);
|
|
791
795
|
copy.addEventListener("click", () => {
|
|
792
|
-
void writeText(
|
|
796
|
+
void writeText(text4).then((ok) => {
|
|
793
797
|
confirm(copy, ok ? strings.copied : strings.copyFailed, strings);
|
|
794
798
|
});
|
|
795
799
|
});
|
|
796
800
|
return copy;
|
|
797
801
|
}
|
|
798
|
-
async function writeText(
|
|
802
|
+
async function writeText(text4) {
|
|
799
803
|
const clipboard = navigator.clipboard;
|
|
800
804
|
if (clipboard === void 0) {
|
|
801
805
|
return false;
|
|
802
806
|
}
|
|
803
807
|
try {
|
|
804
|
-
await clipboard.writeText(
|
|
808
|
+
await clipboard.writeText(text4);
|
|
805
809
|
return true;
|
|
806
810
|
} catch {
|
|
807
811
|
return false;
|
|
@@ -1695,6 +1699,14 @@ var CheckpointMenu = class {
|
|
|
1695
1699
|
}
|
|
1696
1700
|
};
|
|
1697
1701
|
|
|
1702
|
+
// src/ui/clamp_launcher.ts
|
|
1703
|
+
function clampLauncher(launcher, viewport) {
|
|
1704
|
+
return {
|
|
1705
|
+
left: Math.max(0, Math.min(launcher.left, viewport.width - launcher.width)),
|
|
1706
|
+
top: Math.max(0, Math.min(launcher.top, viewport.height - launcher.height))
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1698
1710
|
// src/ui/confirmation_card.ts
|
|
1699
1711
|
function actionButton2(modifier, label) {
|
|
1700
1712
|
const button2 = document.createElement("button");
|
|
@@ -1755,6 +1767,245 @@ function requestConfirmation(host, request, options = {}) {
|
|
|
1755
1767
|
});
|
|
1756
1768
|
}
|
|
1757
1769
|
|
|
1770
|
+
// src/ui/copy_payload.ts
|
|
1771
|
+
var BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
1772
|
+
"ADDRESS",
|
|
1773
|
+
"ARTICLE",
|
|
1774
|
+
"ASIDE",
|
|
1775
|
+
"BLOCKQUOTE",
|
|
1776
|
+
"DD",
|
|
1777
|
+
"DIV",
|
|
1778
|
+
"DL",
|
|
1779
|
+
"DT",
|
|
1780
|
+
"FIGCAPTION",
|
|
1781
|
+
"FIGURE",
|
|
1782
|
+
"FOOTER",
|
|
1783
|
+
"H1",
|
|
1784
|
+
"H2",
|
|
1785
|
+
"H3",
|
|
1786
|
+
"H4",
|
|
1787
|
+
"H5",
|
|
1788
|
+
"H6",
|
|
1789
|
+
"HEADER",
|
|
1790
|
+
"HR",
|
|
1791
|
+
"MAIN",
|
|
1792
|
+
"NAV",
|
|
1793
|
+
"OL",
|
|
1794
|
+
"P",
|
|
1795
|
+
"SECTION",
|
|
1796
|
+
"UL"
|
|
1797
|
+
]);
|
|
1798
|
+
function copyPayload(root) {
|
|
1799
|
+
const clone2 = root.cloneNode(true);
|
|
1800
|
+
for (const control of Array.from(clone2.querySelectorAll("button"))) {
|
|
1801
|
+
control.remove();
|
|
1802
|
+
}
|
|
1803
|
+
return { text: normalise(serialise(clone2)), html: clone2.innerHTML };
|
|
1804
|
+
}
|
|
1805
|
+
function serialise(node) {
|
|
1806
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
1807
|
+
return node.nodeValue.replace(/\s+/g, " ");
|
|
1808
|
+
}
|
|
1809
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
1810
|
+
return "";
|
|
1811
|
+
}
|
|
1812
|
+
const element = node;
|
|
1813
|
+
const tag = element.tagName;
|
|
1814
|
+
if (tag === "BR") {
|
|
1815
|
+
return "\n";
|
|
1816
|
+
}
|
|
1817
|
+
if (tag === "PRE") {
|
|
1818
|
+
return `
|
|
1819
|
+
|
|
1820
|
+
${text2(element)}
|
|
1821
|
+
|
|
1822
|
+
`;
|
|
1823
|
+
}
|
|
1824
|
+
if (tag === "TABLE") {
|
|
1825
|
+
return `
|
|
1826
|
+
|
|
1827
|
+
${tableText(element)}
|
|
1828
|
+
|
|
1829
|
+
`;
|
|
1830
|
+
}
|
|
1831
|
+
if (tag === "UL" || tag === "OL") {
|
|
1832
|
+
return `
|
|
1833
|
+
|
|
1834
|
+
${listText(element, tag === "OL")}
|
|
1835
|
+
|
|
1836
|
+
`;
|
|
1837
|
+
}
|
|
1838
|
+
const inner = children(element);
|
|
1839
|
+
return BLOCK_TAGS.has(tag) ? `
|
|
1840
|
+
|
|
1841
|
+
${inner}
|
|
1842
|
+
|
|
1843
|
+
` : inner;
|
|
1844
|
+
}
|
|
1845
|
+
function children(element) {
|
|
1846
|
+
let joined = "";
|
|
1847
|
+
for (const child of Array.from(element.childNodes)) {
|
|
1848
|
+
joined += serialise(child);
|
|
1849
|
+
}
|
|
1850
|
+
return joined;
|
|
1851
|
+
}
|
|
1852
|
+
function listText(list, numbered) {
|
|
1853
|
+
return Array.from(list.children).map((item, index) => `${numbered ? `${index + 1}. ` : "- "}${children(item).trim()}`).join("\n");
|
|
1854
|
+
}
|
|
1855
|
+
function tableText(table) {
|
|
1856
|
+
return Array.from(table.querySelectorAll("tr")).map(
|
|
1857
|
+
(row) => Array.from(row.children).map((cell) => text2(cell).replace(/\s+/g, " ").trim()).join(" ")
|
|
1858
|
+
).join("\n");
|
|
1859
|
+
}
|
|
1860
|
+
function text2(element) {
|
|
1861
|
+
return element.textContent;
|
|
1862
|
+
}
|
|
1863
|
+
function normalise(text4) {
|
|
1864
|
+
return text4.replace(/[^\S\n]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
// src/ui/launcher_drag.ts
|
|
1868
|
+
var DRAG_THRESHOLD = 4;
|
|
1869
|
+
var STEP = 16;
|
|
1870
|
+
var COARSE_STEP = 64;
|
|
1871
|
+
function enableLauncherDrag(launcher, options) {
|
|
1872
|
+
let suppressClick = false;
|
|
1873
|
+
launcher.addEventListener(
|
|
1874
|
+
"click",
|
|
1875
|
+
(event) => {
|
|
1876
|
+
if (!suppressClick || event.detail === 0) {
|
|
1877
|
+
return;
|
|
1878
|
+
}
|
|
1879
|
+
suppressClick = false;
|
|
1880
|
+
event.stopPropagation();
|
|
1881
|
+
event.preventDefault();
|
|
1882
|
+
},
|
|
1883
|
+
true
|
|
1884
|
+
);
|
|
1885
|
+
launcher.addEventListener("pointerdown", (event) => {
|
|
1886
|
+
suppressClick = false;
|
|
1887
|
+
if (!options.enabled()) {
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
const start = options.rect();
|
|
1891
|
+
const originX = event.clientX;
|
|
1892
|
+
const originY = event.clientY;
|
|
1893
|
+
let dragging = false;
|
|
1894
|
+
const onMove = (move) => {
|
|
1895
|
+
const dx = move.clientX - originX;
|
|
1896
|
+
const dy = move.clientY - originY;
|
|
1897
|
+
if (!dragging && Math.hypot(dx, dy) < DRAG_THRESHOLD) {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
dragging = true;
|
|
1901
|
+
launcher.setAttribute("data-dragging", "true");
|
|
1902
|
+
const next = clampLauncher(
|
|
1903
|
+
{ ...start, left: start.left + dx, top: start.top + dy },
|
|
1904
|
+
options.viewport()
|
|
1905
|
+
);
|
|
1906
|
+
options.apply(next.left, next.top);
|
|
1907
|
+
};
|
|
1908
|
+
const onUp = (up) => {
|
|
1909
|
+
window.removeEventListener("pointermove", onMove);
|
|
1910
|
+
window.removeEventListener("pointerup", onUp);
|
|
1911
|
+
if (!dragging) {
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
launcher.removeAttribute("data-dragging");
|
|
1915
|
+
suppressClick = true;
|
|
1916
|
+
const next = clampLauncher(
|
|
1917
|
+
{
|
|
1918
|
+
...start,
|
|
1919
|
+
left: start.left + (up.clientX - originX),
|
|
1920
|
+
top: start.top + (up.clientY - originY)
|
|
1921
|
+
},
|
|
1922
|
+
options.viewport()
|
|
1923
|
+
);
|
|
1924
|
+
options.commit(next.left, next.top);
|
|
1925
|
+
};
|
|
1926
|
+
window.addEventListener("pointermove", onMove);
|
|
1927
|
+
window.addEventListener("pointerup", onUp);
|
|
1928
|
+
});
|
|
1929
|
+
let pending = null;
|
|
1930
|
+
const settle = () => {
|
|
1931
|
+
if (pending === null) {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
const { left, top } = pending;
|
|
1935
|
+
pending = null;
|
|
1936
|
+
options.commit(left, top);
|
|
1937
|
+
};
|
|
1938
|
+
launcher.addEventListener("keydown", (event) => {
|
|
1939
|
+
if (!options.enabled()) {
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
const step = event.shiftKey ? COARSE_STEP : STEP;
|
|
1943
|
+
const rect = options.rect();
|
|
1944
|
+
let moved = null;
|
|
1945
|
+
if (event.key === "ArrowLeft") {
|
|
1946
|
+
moved = { left: rect.left - step, top: rect.top };
|
|
1947
|
+
} else if (event.key === "ArrowRight") {
|
|
1948
|
+
moved = { left: rect.left + step, top: rect.top };
|
|
1949
|
+
} else if (event.key === "ArrowUp") {
|
|
1950
|
+
moved = { left: rect.left, top: rect.top - step };
|
|
1951
|
+
} else if (event.key === "ArrowDown") {
|
|
1952
|
+
moved = { left: rect.left, top: rect.top + step };
|
|
1953
|
+
}
|
|
1954
|
+
if (moved === null) {
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
event.preventDefault();
|
|
1958
|
+
const next = clampLauncher({ ...rect, ...moved }, options.viewport());
|
|
1959
|
+
options.apply(next.left, next.top);
|
|
1960
|
+
pending = next;
|
|
1961
|
+
});
|
|
1962
|
+
launcher.addEventListener("keyup", settle);
|
|
1963
|
+
launcher.addEventListener("blur", settle);
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
// src/ui/launcher_placement.ts
|
|
1967
|
+
var EDGE_MARGIN = 24;
|
|
1968
|
+
function launcherPlacement(launcher, panel, viewport, margin = EDGE_MARGIN) {
|
|
1969
|
+
const roomRunningRight = viewport.width - launcher.left;
|
|
1970
|
+
const roomRunningLeft = launcher.left + launcher.width;
|
|
1971
|
+
const roomRunningDown = viewport.height - launcher.top;
|
|
1972
|
+
const roomRunningUp = launcher.top + launcher.height;
|
|
1973
|
+
const corner = {
|
|
1974
|
+
x: roomRunningRight >= roomRunningLeft ? "left" : "right",
|
|
1975
|
+
y: roomRunningDown >= roomRunningUp ? "top" : "bottom"
|
|
1976
|
+
};
|
|
1977
|
+
const wantedLeft = corner.x === "left" ? launcher.left : launcher.left + launcher.width - panel.width;
|
|
1978
|
+
const wantedTop = corner.y === "top" ? launcher.top : launcher.top + launcher.height - panel.height;
|
|
1979
|
+
const hostLeft = clamp(wantedLeft, margin, viewport.width - margin - panel.width);
|
|
1980
|
+
const hostTop = clamp(wantedTop, margin, viewport.height - margin - panel.height);
|
|
1981
|
+
const hostRight = hostLeft + panel.width;
|
|
1982
|
+
const hostBottom = hostTop + panel.height;
|
|
1983
|
+
return {
|
|
1984
|
+
corner,
|
|
1985
|
+
hostInset: inset({
|
|
1986
|
+
top: corner.y === "top" ? hostTop : null,
|
|
1987
|
+
right: corner.x === "right" ? viewport.width - hostRight : null,
|
|
1988
|
+
bottom: corner.y === "bottom" ? viewport.height - hostBottom : null,
|
|
1989
|
+
left: corner.x === "left" ? hostLeft : null
|
|
1990
|
+
}),
|
|
1991
|
+
// Measured from the host box's pinned corner to the launcher's matching
|
|
1992
|
+
// corner, so the launcher lands exactly where it was dropped.
|
|
1993
|
+
launcherInset: inset({
|
|
1994
|
+
top: corner.y === "top" ? launcher.top - hostTop : null,
|
|
1995
|
+
right: corner.x === "right" ? hostRight - (launcher.left + launcher.width) : null,
|
|
1996
|
+
bottom: corner.y === "bottom" ? hostBottom - (launcher.top + launcher.height) : null,
|
|
1997
|
+
left: corner.x === "left" ? launcher.left - hostLeft : null
|
|
1998
|
+
})
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
function clamp(value, low, high) {
|
|
2002
|
+
return Math.max(low, Math.min(value, high));
|
|
2003
|
+
}
|
|
2004
|
+
function inset(sides) {
|
|
2005
|
+
const side = (value) => value === null ? "auto" : `${Math.round(value)}px`;
|
|
2006
|
+
return `${side(sides.top)} ${side(sides.right)} ${side(sides.bottom)} ${side(sides.left)}`;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1758
2009
|
// src/ui/message_actions.ts
|
|
1759
2010
|
var CONFIRM_MS2 = 1500;
|
|
1760
2011
|
function attachMessageActions(bubble, options) {
|
|
@@ -1762,9 +2013,9 @@ function attachMessageActions(bubble, options) {
|
|
|
1762
2013
|
return;
|
|
1763
2014
|
}
|
|
1764
2015
|
const bar = messageActionBar(bubble, options.strings);
|
|
1765
|
-
const
|
|
1766
|
-
if (
|
|
1767
|
-
bar.appendChild(copyButton(options.strings,
|
|
2016
|
+
const text4 = options.text;
|
|
2017
|
+
if (text4 !== void 0) {
|
|
2018
|
+
bar.appendChild(copyButton(options.strings, text4, options.html));
|
|
1768
2019
|
}
|
|
1769
2020
|
if (options.onFeedback !== void 0) {
|
|
1770
2021
|
bar.append(
|
|
@@ -1790,36 +2041,63 @@ function existingBar(bubble) {
|
|
|
1790
2041
|
const next = bubble.nextElementSibling;
|
|
1791
2042
|
return next?.classList.contains("message-actions") === true ? next : null;
|
|
1792
2043
|
}
|
|
1793
|
-
function messageActionButton(modifier, label,
|
|
2044
|
+
function messageActionButton(modifier, label, icon) {
|
|
1794
2045
|
const button2 = document.createElement("button");
|
|
1795
2046
|
button2.type = "button";
|
|
1796
2047
|
button2.className = `message-action message-action--${modifier}`;
|
|
1797
2048
|
button2.setAttribute("part", `message-action message-action-${modifier}`);
|
|
2049
|
+
setLabel(button2, label);
|
|
2050
|
+
const holder = document.createElement("span");
|
|
2051
|
+
holder.className = "message-action-icon";
|
|
2052
|
+
holder.setAttribute("part", `message-action-icon message-action-icon-${modifier}`);
|
|
2053
|
+
holder.setAttribute("aria-hidden", "true");
|
|
2054
|
+
holder.innerHTML = icon;
|
|
2055
|
+
button2.appendChild(holder);
|
|
2056
|
+
return button2;
|
|
2057
|
+
}
|
|
2058
|
+
function setLabel(button2, label) {
|
|
1798
2059
|
button2.title = label;
|
|
1799
2060
|
button2.setAttribute("aria-label", label);
|
|
1800
|
-
|
|
1801
|
-
icon.setAttribute("aria-hidden", "true");
|
|
1802
|
-
icon.textContent = glyph;
|
|
1803
|
-
button2.appendChild(icon);
|
|
1804
|
-
return button2;
|
|
2061
|
+
button2.dataset["tooltip"] = label;
|
|
1805
2062
|
}
|
|
1806
|
-
function copyButton(strings,
|
|
1807
|
-
const button2 = messageActionButton("copy", strings.copyMessage,
|
|
2063
|
+
function copyButton(strings, text4, html2) {
|
|
2064
|
+
const button2 = messageActionButton("copy", strings.copyMessage, ICON_COPY);
|
|
1808
2065
|
button2.addEventListener("click", () => {
|
|
1809
|
-
void
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
// say so on the button rather than throwing into an unhandled rejection.
|
|
1813
|
-
() => flash2(button2, strings.copyFailed, strings.copyMessage)
|
|
1814
|
-
);
|
|
2066
|
+
void write(text4(), html2?.()).then((ok) => {
|
|
2067
|
+
flash2(button2, ok ? strings.copied : strings.copyFailed, strings.copyMessage);
|
|
2068
|
+
});
|
|
1815
2069
|
});
|
|
1816
2070
|
return button2;
|
|
1817
2071
|
}
|
|
2072
|
+
async function write(text4, html2) {
|
|
2073
|
+
const clipboard = navigator.clipboard;
|
|
2074
|
+
if (clipboard === void 0) {
|
|
2075
|
+
return false;
|
|
2076
|
+
}
|
|
2077
|
+
if (html2 !== void 0 && typeof ClipboardItem === "function") {
|
|
2078
|
+
try {
|
|
2079
|
+
await clipboard.write([
|
|
2080
|
+
new ClipboardItem({
|
|
2081
|
+
"text/plain": new Blob([text4], { type: "text/plain" }),
|
|
2082
|
+
"text/html": new Blob([html2], { type: "text/html" })
|
|
2083
|
+
})
|
|
2084
|
+
]);
|
|
2085
|
+
return true;
|
|
2086
|
+
} catch {
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
try {
|
|
2090
|
+
await clipboard.writeText(text4);
|
|
2091
|
+
return true;
|
|
2092
|
+
} catch {
|
|
2093
|
+
return false;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
1818
2096
|
function feedbackButton(rating, label, report) {
|
|
1819
2097
|
const button2 = messageActionButton(
|
|
1820
2098
|
rating === "up" ? "up" : "down",
|
|
1821
2099
|
label,
|
|
1822
|
-
rating === "up" ?
|
|
2100
|
+
rating === "up" ? ICON_THUMB_UP : ICON_THUMB_DOWN
|
|
1823
2101
|
);
|
|
1824
2102
|
button2.addEventListener("click", () => {
|
|
1825
2103
|
const pressed = button2.getAttribute("aria-pressed") === "true";
|
|
@@ -1830,12 +2108,10 @@ function feedbackButton(rating, label, report) {
|
|
|
1830
2108
|
return button2;
|
|
1831
2109
|
}
|
|
1832
2110
|
function flash2(button2, message, label) {
|
|
1833
|
-
button2
|
|
1834
|
-
button2.setAttribute("aria-label", message);
|
|
2111
|
+
setLabel(button2, message);
|
|
1835
2112
|
button2.classList.add("message-action--confirmed");
|
|
1836
2113
|
setTimeout(() => {
|
|
1837
|
-
button2
|
|
1838
|
-
button2.setAttribute("aria-label", label);
|
|
2114
|
+
setLabel(button2, label);
|
|
1839
2115
|
button2.classList.remove("message-action--confirmed");
|
|
1840
2116
|
}, CONFIRM_MS2);
|
|
1841
2117
|
}
|
|
@@ -1853,16 +2129,16 @@ function quotableSelection(container, roots = [], near) {
|
|
|
1853
2129
|
const range = document.createRange();
|
|
1854
2130
|
range.setStart(endpoints.startContainer, endpoints.startOffset);
|
|
1855
2131
|
range.setEnd(endpoints.endContainer, endpoints.endOffset);
|
|
1856
|
-
const
|
|
1857
|
-
if (
|
|
2132
|
+
const text4 = renderedText(range).trim();
|
|
2133
|
+
if (text4 === "") {
|
|
1858
2134
|
continue;
|
|
1859
2135
|
}
|
|
1860
|
-
return { text:
|
|
2136
|
+
return { text: text4, rect: lineToHangFrom(range, near) };
|
|
1861
2137
|
}
|
|
1862
2138
|
return null;
|
|
1863
2139
|
}
|
|
1864
|
-
function asQuote(
|
|
1865
|
-
const lines = tidy(
|
|
2140
|
+
function asQuote(text4) {
|
|
2141
|
+
const lines = tidy(text4);
|
|
1866
2142
|
if (lines.length === 0) {
|
|
1867
2143
|
return "";
|
|
1868
2144
|
}
|
|
@@ -1872,8 +2148,8 @@ function asQuote(text3) {
|
|
|
1872
2148
|
|
|
1873
2149
|
`;
|
|
1874
2150
|
}
|
|
1875
|
-
function tidy(
|
|
1876
|
-
const lines =
|
|
2151
|
+
function tidy(text4) {
|
|
2152
|
+
const lines = text4.split(/\r\n?|\n/).map((line) => line.trimEnd());
|
|
1877
2153
|
const indents = lines.filter((line) => line !== "").map(indentOf);
|
|
1878
2154
|
const shared = indents.length === 0 ? 0 : Math.min(...indents);
|
|
1879
2155
|
const kept = [];
|
|
@@ -1892,11 +2168,11 @@ function tidy(text3) {
|
|
|
1892
2168
|
function indentOf(line) {
|
|
1893
2169
|
return line.length - line.trimStart().length;
|
|
1894
2170
|
}
|
|
1895
|
-
function cap(
|
|
1896
|
-
return
|
|
2171
|
+
function cap(text4) {
|
|
2172
|
+
return text4.length > MAX_QUOTE_CHARS ? `${text4.slice(0, MAX_QUOTE_CHARS).trimEnd()}...` : text4;
|
|
1897
2173
|
}
|
|
1898
2174
|
function renderedText(range) {
|
|
1899
|
-
let
|
|
2175
|
+
let text4 = "";
|
|
1900
2176
|
for (const node of textNodesIn(range)) {
|
|
1901
2177
|
const parent = node.parentElement;
|
|
1902
2178
|
if (!isRendered(parent)) {
|
|
@@ -1904,15 +2180,15 @@ function renderedText(range) {
|
|
|
1904
2180
|
}
|
|
1905
2181
|
const from = node === range.startContainer ? range.startOffset : 0;
|
|
1906
2182
|
const to = node === range.endContainer ? range.endOffset : node.data.length;
|
|
1907
|
-
|
|
2183
|
+
text4 += collapse(node.data.slice(from, to), parent);
|
|
1908
2184
|
}
|
|
1909
|
-
return
|
|
2185
|
+
return text4;
|
|
1910
2186
|
}
|
|
1911
|
-
function collapse(
|
|
2187
|
+
function collapse(text4, parent) {
|
|
1912
2188
|
if (PREFORMATTED.has(whiteSpaceOf(parent))) {
|
|
1913
|
-
return
|
|
2189
|
+
return text4;
|
|
1914
2190
|
}
|
|
1915
|
-
return
|
|
2191
|
+
return text4.replace(/[^\S\n]*\n[^\S\n]*/g, "\n").replace(/[^\S\n]+/g, " ");
|
|
1916
2192
|
}
|
|
1917
2193
|
var PREFORMATTED = /* @__PURE__ */ new Set(["pre", "pre-wrap", "break-spaces"]);
|
|
1918
2194
|
function whiteSpaceOf(element) {
|
|
@@ -2062,10 +2338,10 @@ function attachQuoteOffer(options) {
|
|
|
2062
2338
|
event.preventDefault();
|
|
2063
2339
|
});
|
|
2064
2340
|
button2.addEventListener("click", () => {
|
|
2065
|
-
const
|
|
2341
|
+
const text4 = quoting;
|
|
2066
2342
|
window.getSelection()?.removeAllRanges();
|
|
2067
2343
|
hide();
|
|
2068
|
-
onQuote(
|
|
2344
|
+
onQuote(text4);
|
|
2069
2345
|
});
|
|
2070
2346
|
return {
|
|
2071
2347
|
element: button2,
|
|
@@ -2145,10 +2421,10 @@ function requestQuestion(host, request, options = {}) {
|
|
|
2145
2421
|
radio.name = group;
|
|
2146
2422
|
radio.value = choice;
|
|
2147
2423
|
radio.setAttribute("part", "question-radio");
|
|
2148
|
-
const
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
label.append(radio,
|
|
2424
|
+
const text4 = document.createElement("span");
|
|
2425
|
+
text4.setAttribute("part", "question-choice-text");
|
|
2426
|
+
text4.textContent = choice;
|
|
2427
|
+
label.append(radio, text4);
|
|
2152
2428
|
form.appendChild(label);
|
|
2153
2429
|
radios.push(radio);
|
|
2154
2430
|
}
|
|
@@ -2165,10 +2441,10 @@ function requestQuestion(host, request, options = {}) {
|
|
|
2165
2441
|
otherRadio.name = group;
|
|
2166
2442
|
otherRadio.value = "";
|
|
2167
2443
|
otherRadio.setAttribute("part", "question-radio");
|
|
2168
|
-
const
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
label.append(otherRadio,
|
|
2444
|
+
const text4 = document.createElement("span");
|
|
2445
|
+
text4.setAttribute("part", "question-choice-text");
|
|
2446
|
+
text4.textContent = strings.otherOption;
|
|
2447
|
+
label.append(otherRadio, text4);
|
|
2172
2448
|
form.appendChild(label);
|
|
2173
2449
|
input.disabled = true;
|
|
2174
2450
|
}
|
|
@@ -2250,7 +2526,7 @@ function requestQuestion(host, request, options = {}) {
|
|
|
2250
2526
|
});
|
|
2251
2527
|
}
|
|
2252
2528
|
|
|
2253
|
-
// node_modules/.pnpm/dompurify@3.4.
|
|
2529
|
+
// node_modules/.pnpm/dompurify@3.4.14/node_modules/dompurify/dist/purify.es.mjs
|
|
2254
2530
|
function _arrayLikeToArray(r, a) {
|
|
2255
2531
|
(null == a || a > r.length) && (a = r.length);
|
|
2256
2532
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
@@ -2489,9 +2765,9 @@ var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feC
|
|
|
2489
2765
|
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"]);
|
|
2490
2766
|
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"]);
|
|
2491
2767
|
var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
|
|
2492
|
-
var
|
|
2768
|
+
var text3 = freeze(["#text"]);
|
|
2493
2769
|
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"]);
|
|
2494
|
-
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", "dominant-baseline", "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-orientation", "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"]);
|
|
2770
|
+
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", "dominant-baseline", "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", "pointer-events", "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-orientation", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "vector-effect", "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"]);
|
|
2495
2771
|
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"]);
|
|
2496
2772
|
var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
|
|
2497
2773
|
var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
|
|
@@ -2531,6 +2807,15 @@ var NODE_TYPE = {
|
|
|
2531
2807
|
notation: 12
|
|
2532
2808
|
// Deprecated
|
|
2533
2809
|
};
|
|
2810
|
+
var LITERAL_TEXT_ELEMENT_NAMES = ["style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript"];
|
|
2811
|
+
var LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
|
|
2812
|
+
var LITERAL_TEXT_CLOSE = (function() {
|
|
2813
|
+
const map = {};
|
|
2814
|
+
arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
|
|
2815
|
+
map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
|
|
2816
|
+
});
|
|
2817
|
+
return freeze(map);
|
|
2818
|
+
})();
|
|
2534
2819
|
var getGlobal = function getGlobal2() {
|
|
2535
2820
|
return typeof window === "undefined" ? null : window;
|
|
2536
2821
|
};
|
|
@@ -2574,10 +2859,14 @@ var _createHooksMap = function _createHooksMap2() {
|
|
|
2574
2859
|
var _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
|
|
2575
2860
|
return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
|
|
2576
2861
|
};
|
|
2862
|
+
var _resolveObjectOption = function _resolveObjectOption2(cfg, key, makeFallback) {
|
|
2863
|
+
const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
|
|
2864
|
+
return value && typeof value === "object" ? clone(value) : makeFallback();
|
|
2865
|
+
};
|
|
2577
2866
|
function createDOMPurify() {
|
|
2578
2867
|
let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
|
|
2579
2868
|
const DOMPurify = (root) => createDOMPurify(root);
|
|
2580
|
-
DOMPurify.version = "3.4.
|
|
2869
|
+
DOMPurify.version = "3.4.14";
|
|
2581
2870
|
DOMPurify.removed = [];
|
|
2582
2871
|
if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
|
|
2583
2872
|
DOMPurify.isSupported = false;
|
|
@@ -2602,6 +2891,12 @@ function createDOMPurify() {
|
|
|
2602
2891
|
const getNodeType = Node2 && Node2.prototype ? lookupGetter(Node2.prototype, "nodeType") : null;
|
|
2603
2892
|
const getNodeName = Node2 && Node2.prototype ? lookupGetter(Node2.prototype, "nodeName") : null;
|
|
2604
2893
|
const getOwnerDocument = Node2 && Node2.prototype ? lookupGetter(Node2.prototype, "ownerDocument") : null;
|
|
2894
|
+
const _readNodeType = function _readNodeType2(node) {
|
|
2895
|
+
return getNodeType ? getNodeType(node) : node.nodeType;
|
|
2896
|
+
};
|
|
2897
|
+
const _readNodeName = function _readNodeName2(node) {
|
|
2898
|
+
return getNodeName ? getNodeName(node) : node.nodeName;
|
|
2899
|
+
};
|
|
2605
2900
|
if (typeof HTMLTemplateElement === "function") {
|
|
2606
2901
|
const template = document2.createElement("template");
|
|
2607
2902
|
if (template.content && template.content.ownerDocument) {
|
|
@@ -2650,7 +2945,7 @@ function createDOMPurify() {
|
|
|
2650
2945
|
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;
|
|
2651
2946
|
let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
|
|
2652
2947
|
let ALLOWED_TAGS2 = null;
|
|
2653
|
-
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...
|
|
2948
|
+
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text3]);
|
|
2654
2949
|
let ALLOWED_ATTR2 = null;
|
|
2655
2950
|
const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
|
|
2656
2951
|
let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
@@ -2828,9 +3123,19 @@ function createDOMPurify() {
|
|
|
2828
3123
|
IN_PLACE = cfg.IN_PLACE || false;
|
|
2829
3124
|
IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
|
|
2830
3125
|
NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
|
|
2831
|
-
MATHML_TEXT_INTEGRATION_POINTS =
|
|
2832
|
-
|
|
2833
|
-
|
|
3126
|
+
MATHML_TEXT_INTEGRATION_POINTS = _resolveObjectOption(
|
|
3127
|
+
cfg,
|
|
3128
|
+
"MATHML_TEXT_INTEGRATION_POINTS",
|
|
3129
|
+
() => addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS)
|
|
3130
|
+
// Default built-in map
|
|
3131
|
+
);
|
|
3132
|
+
HTML_INTEGRATION_POINTS = _resolveObjectOption(
|
|
3133
|
+
cfg,
|
|
3134
|
+
"HTML_INTEGRATION_POINTS",
|
|
3135
|
+
() => addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS)
|
|
3136
|
+
// Default built-in map
|
|
3137
|
+
);
|
|
3138
|
+
const customElementHandling = _resolveObjectOption(cfg, "CUSTOM_ELEMENT_HANDLING", () => create(null));
|
|
2834
3139
|
CUSTOM_ELEMENT_HANDLING = create(null);
|
|
2835
3140
|
if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
|
|
2836
3141
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
|
|
@@ -2849,7 +3154,7 @@ function createDOMPurify() {
|
|
|
2849
3154
|
RETURN_DOM = true;
|
|
2850
3155
|
}
|
|
2851
3156
|
if (USE_PROFILES) {
|
|
2852
|
-
ALLOWED_TAGS2 = addToSet({},
|
|
3157
|
+
ALLOWED_TAGS2 = addToSet({}, text3);
|
|
2853
3158
|
ALLOWED_ATTR2 = create(null);
|
|
2854
3159
|
if (USE_PROFILES.html === true) {
|
|
2855
3160
|
addToSet(ALLOWED_TAGS2, html$1);
|
|
@@ -2893,15 +3198,6 @@ function createDOMPurify() {
|
|
|
2893
3198
|
addToSet(ALLOWED_ATTR2, cfg.ADD_ATTR, transformCaseFunc);
|
|
2894
3199
|
}
|
|
2895
3200
|
}
|
|
2896
|
-
if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
|
|
2897
|
-
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
2898
|
-
}
|
|
2899
|
-
if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
|
|
2900
|
-
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
2901
|
-
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
2902
|
-
}
|
|
2903
|
-
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
2904
|
-
}
|
|
2905
3201
|
if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
|
|
2906
3202
|
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
2907
3203
|
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
@@ -3018,6 +3314,16 @@ function createDOMPurify() {
|
|
|
3018
3314
|
}
|
|
3019
3315
|
}
|
|
3020
3316
|
};
|
|
3317
|
+
const _stripAttributeNode = function _stripAttributeNode2(element, attribute, name) {
|
|
3318
|
+
try {
|
|
3319
|
+
element.removeAttributeNode(attribute);
|
|
3320
|
+
} catch (_2) {
|
|
3321
|
+
try {
|
|
3322
|
+
element.removeAttribute(name);
|
|
3323
|
+
} catch (_3) {
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
};
|
|
3021
3327
|
const _neutralizeRoot = function _neutralizeRoot2(root) {
|
|
3022
3328
|
_neutralizeSubtree(root);
|
|
3023
3329
|
const childNodes = getChildNodes(root);
|
|
@@ -3039,27 +3345,35 @@ function createDOMPurify() {
|
|
|
3039
3345
|
const attribute = attributes[i];
|
|
3040
3346
|
const name = attribute && attribute.name;
|
|
3041
3347
|
if (typeof name === "string") {
|
|
3042
|
-
|
|
3043
|
-
root.removeAttribute(name);
|
|
3044
|
-
} catch (_2) {
|
|
3045
|
-
}
|
|
3348
|
+
_stripAttributeNode(root, attribute, name);
|
|
3046
3349
|
}
|
|
3047
3350
|
}
|
|
3048
3351
|
}
|
|
3049
3352
|
};
|
|
3050
|
-
const _removeAttribute = function _removeAttribute2(name, element) {
|
|
3353
|
+
const _removeAttribute = function _removeAttribute2(name, element, attr) {
|
|
3354
|
+
if (!attr) {
|
|
3355
|
+
try {
|
|
3356
|
+
attr = element.getAttributeNode(name);
|
|
3357
|
+
} catch (_2) {
|
|
3358
|
+
attr = null;
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
arrayPush(DOMPurify.removed, {
|
|
3362
|
+
attribute: attr || null,
|
|
3363
|
+
from: element
|
|
3364
|
+
});
|
|
3051
3365
|
try {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3366
|
+
if (attr) {
|
|
3367
|
+
element.removeAttributeNode(attr);
|
|
3368
|
+
} else {
|
|
3369
|
+
element.removeAttribute(name);
|
|
3370
|
+
}
|
|
3056
3371
|
} catch (_2) {
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
}
|
|
3372
|
+
try {
|
|
3373
|
+
element.removeAttribute(name);
|
|
3374
|
+
} catch (_3) {
|
|
3375
|
+
}
|
|
3061
3376
|
}
|
|
3062
|
-
element.removeAttribute(name);
|
|
3063
3377
|
if (name === "is") {
|
|
3064
3378
|
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
3065
3379
|
try {
|
|
@@ -3085,17 +3399,14 @@ function createDOMPurify() {
|
|
|
3085
3399
|
if (typeof name !== "string" || ALLOWED_ATTR2[transformCaseFunc(name)]) {
|
|
3086
3400
|
continue;
|
|
3087
3401
|
}
|
|
3088
|
-
|
|
3089
|
-
element.removeAttribute(name);
|
|
3090
|
-
} catch (_2) {
|
|
3091
|
-
}
|
|
3402
|
+
_stripAttributeNode(element, attribute, name);
|
|
3092
3403
|
}
|
|
3093
3404
|
};
|
|
3094
3405
|
const _neutralizeSubtree = function _neutralizeSubtree2(root) {
|
|
3095
3406
|
const stack = [root];
|
|
3096
3407
|
while (stack.length > 0) {
|
|
3097
3408
|
const node = stack.pop();
|
|
3098
|
-
const nodeType =
|
|
3409
|
+
const nodeType = _readNodeType(node);
|
|
3099
3410
|
if (nodeType === NODE_TYPE.element) {
|
|
3100
3411
|
_stripDisallowedAttributes(node);
|
|
3101
3412
|
}
|
|
@@ -3107,6 +3418,15 @@ function createDOMPurify() {
|
|
|
3107
3418
|
}
|
|
3108
3419
|
}
|
|
3109
3420
|
};
|
|
3421
|
+
const _isPatchLinkageAttribute = function _isPatchLinkageAttribute2(lcName, lcTag) {
|
|
3422
|
+
if (!SAFE_FOR_XML) {
|
|
3423
|
+
return false;
|
|
3424
|
+
}
|
|
3425
|
+
if (lcName === "patchsrc") {
|
|
3426
|
+
return true;
|
|
3427
|
+
}
|
|
3428
|
+
return lcName === "for" && lcTag !== "label" && lcTag !== "output";
|
|
3429
|
+
};
|
|
3110
3430
|
const _neutralizePatchLinkage = function _neutralizePatchLinkage2(root) {
|
|
3111
3431
|
if (!SAFE_FOR_XML) {
|
|
3112
3432
|
return;
|
|
@@ -3114,7 +3434,7 @@ function createDOMPurify() {
|
|
|
3114
3434
|
const stack = [root];
|
|
3115
3435
|
while (stack.length > 0) {
|
|
3116
3436
|
const node = stack.pop();
|
|
3117
|
-
const nodeType =
|
|
3437
|
+
const nodeType = _readNodeType(node);
|
|
3118
3438
|
if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
|
|
3119
3439
|
try {
|
|
3120
3440
|
remove(node);
|
|
@@ -3124,12 +3444,12 @@ function createDOMPurify() {
|
|
|
3124
3444
|
}
|
|
3125
3445
|
if (nodeType === NODE_TYPE.element) {
|
|
3126
3446
|
const element = node;
|
|
3127
|
-
const lcTag = transformCaseFunc(
|
|
3447
|
+
const lcTag = transformCaseFunc(_readNodeName(node));
|
|
3128
3448
|
try {
|
|
3129
3449
|
if (element.hasAttribute && element.hasAttribute("patchsrc")) {
|
|
3130
3450
|
element.removeAttribute("patchsrc");
|
|
3131
3451
|
}
|
|
3132
|
-
if (element.hasAttribute && element.hasAttribute("for") &&
|
|
3452
|
+
if (element.hasAttribute && element.hasAttribute("for") && _isPatchLinkageAttribute("for", lcTag)) {
|
|
3133
3453
|
element.removeAttribute("for");
|
|
3134
3454
|
}
|
|
3135
3455
|
} catch (_2) {
|
|
@@ -3284,7 +3604,7 @@ function createDOMPurify() {
|
|
|
3284
3604
|
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
|
|
3285
3605
|
return true;
|
|
3286
3606
|
}
|
|
3287
|
-
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "
|
|
3607
|
+
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && LITERAL_TEXT_ELEMENTS[tagName] && (_isNode(currentNode.firstElementChild) || typeof currentNode.textContent === "string" && regExpTest(LITERAL_TEXT_CLOSE[tagName], currentNode.textContent))) {
|
|
3288
3608
|
return true;
|
|
3289
3609
|
}
|
|
3290
3610
|
if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
|
|
@@ -3295,14 +3615,21 @@ function createDOMPurify() {
|
|
|
3295
3615
|
}
|
|
3296
3616
|
return false;
|
|
3297
3617
|
};
|
|
3298
|
-
const
|
|
3299
|
-
if (
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3618
|
+
const _matchesNameCheck = function _matchesNameCheck2(check, name) {
|
|
3619
|
+
if (check instanceof RegExp) {
|
|
3620
|
+
return regExpTest(check, name);
|
|
3621
|
+
}
|
|
3622
|
+
if (check instanceof Function) {
|
|
3623
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
3624
|
+
args[_key - 2] = arguments[_key];
|
|
3305
3625
|
}
|
|
3626
|
+
return Boolean(check(name, ...args));
|
|
3627
|
+
}
|
|
3628
|
+
return false;
|
|
3629
|
+
};
|
|
3630
|
+
const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName, root) {
|
|
3631
|
+
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
3632
|
+
return false;
|
|
3306
3633
|
}
|
|
3307
3634
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
3308
3635
|
const parentNode = getParentNode(currentNode);
|
|
@@ -3324,28 +3651,31 @@ function createDOMPurify() {
|
|
|
3324
3651
|
}
|
|
3325
3652
|
return set === defaultSet || set === setConfigSet ? clone(set) : set;
|
|
3326
3653
|
};
|
|
3654
|
+
const _handleHookDetachedNode = function _handleHookDetachedNode2(currentNode, root) {
|
|
3655
|
+
if (currentNode === root || getParentNode(currentNode) !== null) {
|
|
3656
|
+
return false;
|
|
3657
|
+
}
|
|
3658
|
+
if (IN_PLACE) {
|
|
3659
|
+
_neutralizeSubtree(currentNode);
|
|
3660
|
+
}
|
|
3661
|
+
return true;
|
|
3662
|
+
};
|
|
3327
3663
|
const _sanitizeElements = function _sanitizeElements2(currentNode, root) {
|
|
3328
3664
|
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
|
3329
|
-
if (currentNode
|
|
3330
|
-
if (IN_PLACE) {
|
|
3331
|
-
_neutralizeSubtree(currentNode);
|
|
3332
|
-
}
|
|
3665
|
+
if (_handleHookDetachedNode(currentNode, root)) {
|
|
3333
3666
|
return true;
|
|
3334
3667
|
}
|
|
3335
3668
|
if (_isClobbered(currentNode)) {
|
|
3336
3669
|
_forceRemove(currentNode);
|
|
3337
3670
|
return true;
|
|
3338
3671
|
}
|
|
3339
|
-
const tagName = transformCaseFunc(
|
|
3672
|
+
const tagName = transformCaseFunc(_readNodeName(currentNode));
|
|
3340
3673
|
ALLOWED_TAGS2 = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS2, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
|
|
3341
3674
|
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
3342
3675
|
tagName,
|
|
3343
3676
|
allowedTags: ALLOWED_TAGS2
|
|
3344
3677
|
});
|
|
3345
|
-
if (currentNode
|
|
3346
|
-
if (IN_PLACE) {
|
|
3347
|
-
_neutralizeSubtree(currentNode);
|
|
3348
|
-
}
|
|
3678
|
+
if (_handleHookDetachedNode(currentNode, root)) {
|
|
3349
3679
|
return true;
|
|
3350
3680
|
}
|
|
3351
3681
|
if (_isUnsafeNode(currentNode, tagName)) {
|
|
@@ -3359,7 +3689,7 @@ function createDOMPurify() {
|
|
|
3359
3689
|
}
|
|
3360
3690
|
return removed;
|
|
3361
3691
|
}
|
|
3362
|
-
const nt2 =
|
|
3692
|
+
const nt2 = _readNodeType(currentNode);
|
|
3363
3693
|
if (nt2 === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
|
|
3364
3694
|
_forceRemove(currentNode);
|
|
3365
3695
|
return true;
|
|
@@ -3384,38 +3714,43 @@ function createDOMPurify() {
|
|
|
3384
3714
|
if (FORBID_ATTR[lcName]) {
|
|
3385
3715
|
return false;
|
|
3386
3716
|
}
|
|
3387
|
-
if (
|
|
3388
|
-
return false;
|
|
3389
|
-
}
|
|
3390
|
-
if (SAFE_FOR_XML && lcName === "for" && lcTag !== "label" && lcTag !== "output") {
|
|
3717
|
+
if (_isPatchLinkageAttribute(lcName, lcTag)) {
|
|
3391
3718
|
return false;
|
|
3392
3719
|
}
|
|
3393
3720
|
if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
|
|
3394
3721
|
return false;
|
|
3395
3722
|
}
|
|
3396
3723
|
const nameIsPermitted = ALLOWED_ATTR2[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
|
|
3397
|
-
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName))
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
//
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3724
|
+
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) {
|
|
3725
|
+
return true;
|
|
3726
|
+
}
|
|
3727
|
+
if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) {
|
|
3728
|
+
return true;
|
|
3729
|
+
}
|
|
3730
|
+
if (!nameIsPermitted) {
|
|
3731
|
+
return (
|
|
3732
|
+
// Condition a) covers a basically valid custom element tag name whose
|
|
3733
|
+
// tag passes the configured tagNameCheck and whose attribute name
|
|
3734
|
+
// passes the configured attributeNameCheck ...
|
|
3735
|
+
_isBasicCustomElement(lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName, lcTag) || // Condition b) covers an `is` attribute whose value passes the
|
|
3736
|
+
// configured tagNameCheck while customized built-in elements are
|
|
3737
|
+
// allowed.
|
|
3738
|
+
lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)
|
|
3739
|
+
);
|
|
3740
|
+
}
|
|
3741
|
+
if (URI_SAFE_ATTRIBUTES[lcName]) {
|
|
3742
|
+
return true;
|
|
3743
|
+
}
|
|
3744
|
+
if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) {
|
|
3745
|
+
return true;
|
|
3746
|
+
}
|
|
3747
|
+
if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) {
|
|
3748
|
+
return true;
|
|
3749
|
+
}
|
|
3750
|
+
if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) {
|
|
3751
|
+
return true;
|
|
3752
|
+
}
|
|
3753
|
+
return !value;
|
|
3419
3754
|
};
|
|
3420
3755
|
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"]);
|
|
3421
3756
|
const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
|
|
@@ -3479,33 +3814,33 @@ function createDOMPurify() {
|
|
|
3479
3814
|
_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
|
|
3480
3815
|
value = hookEvent.attrValue;
|
|
3481
3816
|
if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
|
|
3482
|
-
_removeAttribute(name, currentNode);
|
|
3817
|
+
_removeAttribute(name, currentNode, attr);
|
|
3483
3818
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
3484
3819
|
}
|
|
3485
3820
|
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
3486
|
-
_removeAttribute(name, currentNode);
|
|
3821
|
+
_removeAttribute(name, currentNode, attr);
|
|
3487
3822
|
continue;
|
|
3488
3823
|
}
|
|
3489
3824
|
if (lcName === "attributename" && stringMatch(value, "href")) {
|
|
3490
|
-
_removeAttribute(name, currentNode);
|
|
3825
|
+
_removeAttribute(name, currentNode, attr);
|
|
3491
3826
|
continue;
|
|
3492
3827
|
}
|
|
3493
3828
|
if (hookEvent.forceKeepAttr) {
|
|
3494
3829
|
continue;
|
|
3495
3830
|
}
|
|
3496
3831
|
if (!hookEvent.keepAttr) {
|
|
3497
|
-
_removeAttribute(name, currentNode);
|
|
3832
|
+
_removeAttribute(name, currentNode, attr);
|
|
3498
3833
|
continue;
|
|
3499
3834
|
}
|
|
3500
3835
|
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
|
|
3501
|
-
_removeAttribute(name, currentNode);
|
|
3836
|
+
_removeAttribute(name, currentNode, attr);
|
|
3502
3837
|
continue;
|
|
3503
3838
|
}
|
|
3504
3839
|
if (SAFE_FOR_TEMPLATES) {
|
|
3505
3840
|
value = _stripTemplateExpressions(value);
|
|
3506
3841
|
}
|
|
3507
3842
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
3508
|
-
_removeAttribute(name, currentNode);
|
|
3843
|
+
_removeAttribute(name, currentNode, attr);
|
|
3509
3844
|
continue;
|
|
3510
3845
|
}
|
|
3511
3846
|
value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
|
|
@@ -3526,8 +3861,7 @@ function createDOMPurify() {
|
|
|
3526
3861
|
if (_isDocumentFragment(shadowNode.content)) {
|
|
3527
3862
|
_sanitizeShadowDOM2(shadowNode.content);
|
|
3528
3863
|
}
|
|
3529
|
-
|
|
3530
|
-
if (shadowNodeType === NODE_TYPE.element) {
|
|
3864
|
+
if (_readNodeType(shadowNode) === NODE_TYPE.element) {
|
|
3531
3865
|
const innerSr = getShadowRoot(shadowNode);
|
|
3532
3866
|
if (_isDocumentFragment(innerSr)) {
|
|
3533
3867
|
_sanitizeAttachedShadowRoots(innerSr);
|
|
@@ -3549,7 +3883,7 @@ function createDOMPurify() {
|
|
|
3549
3883
|
continue;
|
|
3550
3884
|
}
|
|
3551
3885
|
const node = item.node;
|
|
3552
|
-
const nodeType =
|
|
3886
|
+
const nodeType = _readNodeType(node);
|
|
3553
3887
|
const isElement = nodeType === NODE_TYPE.element;
|
|
3554
3888
|
const childNodes = getChildNodes(node);
|
|
3555
3889
|
if (childNodes) {
|
|
@@ -3621,7 +3955,7 @@ function createDOMPurify() {
|
|
|
3621
3955
|
const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
|
|
3622
3956
|
if (inPlace) {
|
|
3623
3957
|
_neutralizePatchLinkage(dirty);
|
|
3624
|
-
const nn2 =
|
|
3958
|
+
const nn2 = _readNodeName(dirty);
|
|
3625
3959
|
if (typeof nn2 === "string") {
|
|
3626
3960
|
const tagName = transformCaseFunc(nn2);
|
|
3627
3961
|
if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
|
|
@@ -3776,7 +4110,7 @@ function createDOMPurify() {
|
|
|
3776
4110
|
}
|
|
3777
4111
|
var purify = createDOMPurify();
|
|
3778
4112
|
|
|
3779
|
-
// node_modules/.pnpm/marked@18.0.
|
|
4113
|
+
// node_modules/.pnpm/marked@18.0.10/node_modules/marked/lib/marked.esm.js
|
|
3780
4114
|
function C() {
|
|
3781
4115
|
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
3782
4116
|
}
|
|
@@ -3792,7 +4126,7 @@ function A(l3) {
|
|
|
3792
4126
|
return s || (s = l3(n), e[n] = s), s;
|
|
3793
4127
|
};
|
|
3794
4128
|
}
|
|
3795
|
-
function
|
|
4129
|
+
function d(l3, e = "") {
|
|
3796
4130
|
let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (s, r) => {
|
|
3797
4131
|
let i = typeof r == "string" ? r : r.source;
|
|
3798
4132
|
return i = i.replace(m.caret, "$1"), t = t.replace(s, i), n;
|
|
@@ -3814,24 +4148,24 @@ var q = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
|
|
3814
4148
|
var Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
|
|
3815
4149
|
var U = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
|
|
3816
4150
|
var oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
|
|
3817
|
-
var ae =
|
|
3818
|
-
var Se =
|
|
4151
|
+
var ae = d(oe).replace(/bull/g, U).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}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
|
|
4152
|
+
var Se = d(oe).replace(/bull/g, U).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}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
|
|
3819
4153
|
var K = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/;
|
|
3820
4154
|
var _e = /^[^\n]+/;
|
|
3821
4155
|
var W = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
|
|
3822
|
-
var $e =
|
|
3823
|
-
var Le =
|
|
4156
|
+
var $e = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", W).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
|
|
4157
|
+
var Le = d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, U).getRegex();
|
|
3824
4158
|
var Q = "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";
|
|
3825
4159
|
var X = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
|
|
3826
|
-
var Me =
|
|
3827
|
-
var le = (l3) =>
|
|
4160
|
+
var Me = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\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", X).replace("tag", Q).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
|
|
4161
|
+
var le = (l3) => d(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", l3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
|
|
3828
4162
|
var ze = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
|
|
3829
4163
|
var Ee = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
|
|
3830
|
-
var Ce =
|
|
4164
|
+
var Ce = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Ee).getRegex();
|
|
3831
4165
|
var J = { blockquote: Ce, code: we, def: $e, fences: ye, heading: Pe, hr: q, html: Me, lheading: ae, list: Le, newline: Oe, paragraph: ze, table: z, text: _e };
|
|
3832
|
-
var se =
|
|
3833
|
-
var Ae = { ...J, lheading: Se, table: se, paragraph:
|
|
3834
|
-
var Ie = { ...J, html:
|
|
4166
|
+
var se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
|
|
4167
|
+
var Ae = { ...J, lheading: Se, table: se, paragraph: d(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex() };
|
|
4168
|
+
var Ie = { ...J, html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).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: z, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: d(K).replace("hr", q).replace("heading", ` *#{1,6} *[^
|
|
3835
4169
|
]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
|
|
3836
4170
|
var Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
|
|
3837
4171
|
var De = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
@@ -3840,42 +4174,42 @@ var qe = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}
|
|
|
3840
4174
|
var _ = /[\p{P}\p{S}]/u;
|
|
3841
4175
|
var I = /[\s\p{P}\p{S}]/u;
|
|
3842
4176
|
var v = /[^\s\p{P}\p{S}]/u;
|
|
3843
|
-
var ve =
|
|
4177
|
+
var ve = d(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, I).getRegex();
|
|
3844
4178
|
var He = /[\p{Pi}\p{Ps}"']/u;
|
|
3845
4179
|
var ue = /(?!~)[\p{P}\p{S}]/u;
|
|
3846
4180
|
var Ze = /(?!~)[\s\p{P}\p{S}]/u;
|
|
3847
4181
|
var Ge = /(?:[^\s\p{P}\p{S}]|~)/u;
|
|
3848
|
-
var Qe =
|
|
4182
|
+
var Qe = d(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
|
|
3849
4183
|
var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
|
|
3850
|
-
var Ne =
|
|
3851
|
-
var je =
|
|
4184
|
+
var Ne = d(ce, "u").replace(/punct/g, _).getRegex();
|
|
4185
|
+
var je = d(ce, "u").replace(/punct/g, ue).getRegex();
|
|
3852
4186
|
var Fe = /^(?:\*+(?:((?!\*)(?!openQuote)punct)|([^\s*]))?)|^_+(?:((?!_)(?!openQuote)punct)|([^\s_]))?/;
|
|
3853
|
-
var Ue =
|
|
4187
|
+
var Ue = d(Fe, "u").replace(/openQuote/g, He).replace(/punct/g, _).getRegex();
|
|
3854
4188
|
var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
|
|
3855
|
-
var Ke =
|
|
3856
|
-
var We =
|
|
4189
|
+
var Ke = d(he, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, I).replace(/punct/g, _).getRegex();
|
|
4190
|
+
var We = d(he, "gu").replace(/notPunctSpace/g, Ge).replace(/punctSpace/g, Ze).replace(/punct/g, ue).getRegex();
|
|
3857
4191
|
var Xe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)[\\s](\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|(?:(?!\\*)punct|notPunctSpace)(\\*+)(?!\\*)(?=notPunctSpace)";
|
|
3858
|
-
var Je =
|
|
3859
|
-
var Ve =
|
|
4192
|
+
var Je = d(Xe, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, I).replace(/punct/g, _).getRegex();
|
|
4193
|
+
var Ve = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, I).replace(/punct/g, _).getRegex();
|
|
3860
4194
|
var Ye = "^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)[\\s](_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)|(?:(?!_)punct|notPunctSpace)(_+)(?!_)(?=notPunctSpace)";
|
|
3861
|
-
var et =
|
|
3862
|
-
var tt =
|
|
4195
|
+
var et = d(Ye, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, I).replace(/punct/g, _).getRegex();
|
|
4196
|
+
var tt = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, _).getRegex();
|
|
3863
4197
|
var nt = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
|
|
3864
|
-
var rt =
|
|
3865
|
-
var st =
|
|
3866
|
-
var it =
|
|
3867
|
-
var ot =
|
|
3868
|
-
var at =
|
|
4198
|
+
var rt = d(nt, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, I).replace(/punct/g, _).getRegex();
|
|
4199
|
+
var st = d(/\\(punct)/, "gu").replace(/punct/g, _).getRegex();
|
|
4200
|
+
var it = 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();
|
|
4201
|
+
var ot = d(X).replace("(?:-->|$)", "-->").getRegex();
|
|
4202
|
+
var at = 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", ot).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
|
|
3869
4203
|
var G = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
|
|
3870
|
-
var lt =
|
|
3871
|
-
var de =
|
|
3872
|
-
var ke =
|
|
3873
|
-
var pt =
|
|
4204
|
+
var lt = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", G).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
|
|
4205
|
+
var de = d(/^!?\[(label)\]\[(ref)\]/).replace("label", G).replace("ref", W).getRegex();
|
|
4206
|
+
var ke = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", W).getRegex();
|
|
4207
|
+
var pt = d("reflink|nolink(?!\\()", "g").replace("reflink", de).replace("nolink", ke).getRegex();
|
|
3874
4208
|
var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
|
|
3875
4209
|
var V = { _backpedal: z, anyPunctuation: st, autolink: it, blockSkip: Qe, br: pe, code: De, del: z, delLDelim: z, delRDelim: z, emStrongLDelim: Ne, emStrongRDelimAst: Ke, emStrongRDelimUnd: Ve, escape: Be, link: lt, nolink: ke, punctuation: ve, reflink: de, reflinkSearch: pt, tag: at, text: qe, url: z };
|
|
3876
|
-
var ut = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link:
|
|
3877
|
-
var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url:
|
|
3878
|
-
var ct = { ...F, br:
|
|
4210
|
+
var ut = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", G).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", G).getRegex() };
|
|
4211
|
+
var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).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", ie).getRegex() };
|
|
4212
|
+
var ct = { ...F, br: d(pe).replace("{2,}", "*").getRegex(), text: d(F.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
|
|
3879
4213
|
var H = { normal: J, gfm: Ae, pedantic: Ie };
|
|
3880
4214
|
var B = { normal: V, gfm: F, breaks: ct, pedantic: ut };
|
|
3881
4215
|
var ht = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
@@ -4021,20 +4355,20 @@ ${u}` : u, r = r ? `${r}
|
|
|
4021
4355
|
${c}` : c;
|
|
4022
4356
|
let h = this.lexer.state.top;
|
|
4023
4357
|
if (this.lexer.state.top = true, this.lexer.blockTokens(c, i, true), this.lexer.state.top = h, n.length === 0) break;
|
|
4024
|
-
let
|
|
4025
|
-
if (
|
|
4026
|
-
if (
|
|
4027
|
-
let T =
|
|
4358
|
+
let k = i.at(-1);
|
|
4359
|
+
if (k?.type === "code") break;
|
|
4360
|
+
if (k?.type === "blockquote") {
|
|
4361
|
+
let T = k, g = n.join(`
|
|
4028
4362
|
`), w = T.raw + `
|
|
4029
4363
|
` + g.replace(this.rules.other.blockquoteSetextReplace2, ""), M = this.blockquote(w);
|
|
4030
4364
|
i[i.length - 1] = M, s = `${s}
|
|
4031
4365
|
${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
4032
4366
|
break;
|
|
4033
|
-
} else if (
|
|
4034
|
-
let T =
|
|
4367
|
+
} else if (k?.type === "list") {
|
|
4368
|
+
let T = k, g = T.raw + `
|
|
4035
4369
|
` + n.join(`
|
|
4036
4370
|
`), w = this.list(g);
|
|
4037
|
-
i[i.length - 1] = w, s = s.substring(0, s.length -
|
|
4371
|
+
i[i.length - 1] = w, s = s.substring(0, s.length - k.raw.length) + w.raw, r = r.substring(0, r.length - T.raw.length) + w.raw, n = g.substring(i.at(-1).raw.length).split(`
|
|
4038
4372
|
`);
|
|
4039
4373
|
continue;
|
|
4040
4374
|
}
|
|
@@ -4053,23 +4387,23 @@ ${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
|
4053
4387
|
if (!(t = i.exec(e)) || this.rules.block.hr.test(e)) break;
|
|
4054
4388
|
u = t[0], e = e.substring(u.length);
|
|
4055
4389
|
let h = me(t[2].split(`
|
|
4056
|
-
`, 1)[0], t[1].length),
|
|
4390
|
+
`, 1)[0], t[1].length), k = e.split(`
|
|
4057
4391
|
`, 1)[0], T = !h.trim(), g = 0;
|
|
4058
|
-
if (this.options.pedantic ? (g = 2, c = h.trimStart()) : T ? g = t[1].length + 1 : (g = h.search(this.rules.other.nonSpaceChar), g = g > 4 ? 1 : g, c = h.slice(g), g += t[1].length), T && this.rules.other.blankLine.test(
|
|
4059
|
-
`, e = e.substring(
|
|
4392
|
+
if (this.options.pedantic ? (g = 2, c = h.trimStart()) : T ? g = t[1].length + 1 : (g = h.search(this.rules.other.nonSpaceChar), g = g > 4 ? 1 : g, c = h.slice(g), g += t[1].length), T && this.rules.other.blankLine.test(k) && (u += k + `
|
|
4393
|
+
`, e = e.substring(k.length + 1), a = true), !a) {
|
|
4060
4394
|
let w = this.rules.other.nextBulletRegex(g), M = this.rules.other.hrRegex(g), ne = this.rules.other.fencesBeginRegex(g), re = this.rules.other.headingBeginRegex(g), be = this.rules.other.htmlBeginRegex(g), Re = this.rules.other.blockquoteBeginRegex(g);
|
|
4061
4395
|
for (; e; ) {
|
|
4062
4396
|
let N = e.split(`
|
|
4063
4397
|
`, 1)[0], D;
|
|
4064
|
-
if (
|
|
4065
|
-
if (D.search(this.rules.other.nonSpaceChar) >= g || !
|
|
4398
|
+
if (k = N, this.options.pedantic ? (k = k.replace(this.rules.other.listReplaceNesting, " "), D = k) : D = k.replace(this.rules.other.tabCharGlobal, " "), ne.test(k) || re.test(k) || be.test(k) || Re.test(k) || w.test(k) || M.test(k)) break;
|
|
4399
|
+
if (D.search(this.rules.other.nonSpaceChar) >= g || !k.trim()) c += `
|
|
4066
4400
|
` + D.slice(g);
|
|
4067
4401
|
else {
|
|
4068
4402
|
if (T || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || M.test(h)) break;
|
|
4069
4403
|
c += `
|
|
4070
|
-
` +
|
|
4404
|
+
` + k;
|
|
4071
4405
|
}
|
|
4072
|
-
T = !
|
|
4406
|
+
T = !k.trim(), u += N + `
|
|
4073
4407
|
`, e = e.substring(N.length + 1), h = D.slice(g);
|
|
4074
4408
|
}
|
|
4075
4409
|
}
|
|
@@ -4079,8 +4413,11 @@ ${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
|
4079
4413
|
if (p) p.raw = p.raw.trimEnd(), p.text = p.text.trimEnd();
|
|
4080
4414
|
else return;
|
|
4081
4415
|
r.raw = r.raw.trimEnd();
|
|
4416
|
+
for (let a of r.items) if (this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []), !r.loose) {
|
|
4417
|
+
let u = a.tokens.filter((h) => h.type === "space"), c = u.length > 0 && u.some((h) => this.rules.other.anyLine.test(h.raw));
|
|
4418
|
+
r.loose = c;
|
|
4419
|
+
}
|
|
4082
4420
|
for (let a of r.items) {
|
|
4083
|
-
this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []);
|
|
4084
4421
|
let u = a.tokens[0];
|
|
4085
4422
|
if (a.task && (u?.type === "text" || u?.type === "paragraph")) {
|
|
4086
4423
|
a.text = a.text.replace(this.rules.other.listReplaceTask, ""), u.raw = u.raw.replace(this.rules.other.listReplaceTask, ""), u.text = u.text.replace(this.rules.other.listReplaceTask, "");
|
|
@@ -4094,10 +4431,6 @@ ${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
|
4094
4431
|
a.checked = h.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = h.raw + a.tokens[0].raw, a.tokens[0].text = h.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(h)) : a.tokens.unshift({ type: "paragraph", raw: h.raw, text: h.raw, tokens: [h] }) : a.tokens.unshift(h);
|
|
4095
4432
|
}
|
|
4096
4433
|
} else a.task && (a.task = false);
|
|
4097
|
-
if (!r.loose) {
|
|
4098
|
-
let c = a.tokens.filter((d) => d.type === "space"), h = c.length > 0 && c.some((d) => this.rules.other.anyLine.test(d.raw));
|
|
4099
|
-
r.loose = h;
|
|
4100
|
-
}
|
|
4101
4434
|
}
|
|
4102
4435
|
if (r.loose) for (let a of r.items) {
|
|
4103
4436
|
a.loose = true;
|
|
@@ -4201,8 +4534,8 @@ ${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
|
4201
4534
|
let s = this.rules.inline.emStrongLDelim.exec(e);
|
|
4202
4535
|
if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
|
|
4203
4536
|
if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
|
|
4204
|
-
let i = [...s[0]].length - 1, o, p, a = i, u = 0, c = s[0][0], h = n === c,
|
|
4205
|
-
for (
|
|
4537
|
+
let i = [...s[0]].length - 1, o, p, a = i, u = 0, c = s[0][0], h = n === c, k = c === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
4538
|
+
for (k.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = k.exec(t)) !== null; ) {
|
|
4206
4539
|
if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
|
|
4207
4540
|
if (p = [...o].length, s[3] || s[4]) {
|
|
4208
4541
|
a += p;
|
|
@@ -4250,8 +4583,8 @@ ${g}`, r = r.substring(0, r.length - T.text.length) + M.text;
|
|
|
4250
4583
|
}
|
|
4251
4584
|
if (a -= p, a > 0) continue;
|
|
4252
4585
|
p = Math.min(p, p + a);
|
|
4253
|
-
let c = [...s[0]][0].length, h = e.slice(0, i + s.index + c + p),
|
|
4254
|
-
return { type: "del", raw: h, text:
|
|
4586
|
+
let c = [...s[0]][0].length, h = e.slice(0, i + s.index + c + p), k = h.slice(i, -i);
|
|
4587
|
+
return { type: "del", raw: h, text: k, tokens: this.lexer.inlineTokens(k) };
|
|
4255
4588
|
}
|
|
4256
4589
|
}
|
|
4257
4590
|
}
|
|
@@ -4423,7 +4756,7 @@ var x = class l {
|
|
|
4423
4756
|
let o = Object.keys(this.tokens.links);
|
|
4424
4757
|
o.length > 0 && (n = n.replace(this.tokenizer.rules.inline.reflinkSearch, (p) => o.includes(p.slice(p.lastIndexOf("[") + 1, -1)) ? "[" + "a".repeat(p.length - 2) + "]" : p));
|
|
4425
4758
|
}
|
|
4426
|
-
n = n.replace(this.tokenizer.rules.inline.anyPunctuation, "
|
|
4759
|
+
n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (o) => "+".repeat(o.length)), n = n.replace(this.tokenizer.rules.inline.blockSkip, (o, p, a) => {
|
|
4427
4760
|
let u = a ? a.length : 0;
|
|
4428
4761
|
return o.slice(0, u) + "[" + "a".repeat(o.length - u - 2) + "]";
|
|
4429
4762
|
}), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
|
|
@@ -4969,8 +5302,8 @@ var Z = class {
|
|
|
4969
5302
|
if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => {
|
|
4970
5303
|
let p = i.hooks ? await i.hooks.preprocess(n) : n, u = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(p, i), c = i.hooks ? await i.hooks.processAllTokens(u) : u;
|
|
4971
5304
|
i.walkTokens && await Promise.all(this.walkTokens(c, i.walkTokens));
|
|
4972
|
-
let
|
|
4973
|
-
return i.hooks ? await i.hooks.postprocess(
|
|
5305
|
+
let k = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, i);
|
|
5306
|
+
return i.hooks ? await i.hooks.postprocess(k) : k;
|
|
4974
5307
|
})().catch(o);
|
|
4975
5308
|
try {
|
|
4976
5309
|
i.hooks && (n = i.hooks.preprocess(n));
|
|
@@ -5103,46 +5436,43 @@ function sanitizer() {
|
|
|
5103
5436
|
}
|
|
5104
5437
|
return purifier;
|
|
5105
5438
|
}
|
|
5106
|
-
function renderMarkdown(
|
|
5439
|
+
function renderMarkdown(text4, options) {
|
|
5107
5440
|
const allowImages = options?.allowImages === true;
|
|
5108
|
-
const rendered = parser.parse(
|
|
5441
|
+
const rendered = parser.parse(text4, { async: false });
|
|
5109
5442
|
return sanitizer().sanitize(rendered, allowImages ? SANITIZE_CONFIG_WITH_IMAGES : SANITIZE_CONFIG).trim();
|
|
5110
5443
|
}
|
|
5111
5444
|
|
|
5112
5445
|
// src/ui/resize_handle.ts
|
|
5113
5446
|
var MIN_WIDTH = 280;
|
|
5114
5447
|
var MIN_HEIGHT = 240;
|
|
5115
|
-
|
|
5448
|
+
var STEP2 = 16;
|
|
5449
|
+
var COARSE_STEP2 = 64;
|
|
5450
|
+
function createResizeHandle(grip, options) {
|
|
5116
5451
|
const handle = document.createElement("div");
|
|
5117
|
-
handle.className =
|
|
5118
|
-
handle.setAttribute("part",
|
|
5452
|
+
handle.className = `resize-handle resize-handle--${gripName(grip)}`;
|
|
5453
|
+
handle.setAttribute("part", `resize-handle resize-handle-${gripName(grip)}`);
|
|
5119
5454
|
handle.setAttribute("role", "separator");
|
|
5455
|
+
if (grip.x === void 0) {
|
|
5456
|
+
handle.setAttribute("aria-orientation", "horizontal");
|
|
5457
|
+
} else if (grip.y === void 0) {
|
|
5458
|
+
handle.setAttribute("aria-orientation", "vertical");
|
|
5459
|
+
}
|
|
5120
5460
|
handle.setAttribute("aria-label", options.label);
|
|
5121
5461
|
handle.tabIndex = 0;
|
|
5122
|
-
const sizeAt = (axis, anchor, rect, x2, y2) => {
|
|
5123
|
-
const width = anchor.x === "right" ? rect.right - x2 : x2 - rect.left;
|
|
5124
|
-
const clamped = { width: Math.max(MIN_WIDTH, width) };
|
|
5125
|
-
if (axis !== "both") {
|
|
5126
|
-
return clamped;
|
|
5127
|
-
}
|
|
5128
|
-
const height = anchor.y === "bottom" ? rect.bottom - y2 : y2 - rect.top;
|
|
5129
|
-
return { ...clamped, height: Math.max(MIN_HEIGHT, height) };
|
|
5130
|
-
};
|
|
5131
5462
|
handle.addEventListener("pointerdown", (event) => {
|
|
5132
5463
|
const axis = options.axis();
|
|
5133
|
-
if (axis === "none") {
|
|
5464
|
+
if (axis === "none" || !movable(grip, axis)) {
|
|
5134
5465
|
return;
|
|
5135
5466
|
}
|
|
5136
|
-
const anchor = options.anchor();
|
|
5137
5467
|
const rect = options.rect();
|
|
5138
5468
|
const onMove = (move) => {
|
|
5139
|
-
options.apply(
|
|
5469
|
+
options.apply(boxAt(grip, axis, rect, move.clientX, move.clientY));
|
|
5140
5470
|
};
|
|
5141
5471
|
const onUp = (up) => {
|
|
5142
5472
|
window.removeEventListener("pointermove", onMove);
|
|
5143
5473
|
window.removeEventListener("pointerup", onUp);
|
|
5144
5474
|
handle.removeAttribute("data-dragging");
|
|
5145
|
-
options.commit(
|
|
5475
|
+
options.commit(boxAt(grip, axis, rect, up.clientX, up.clientY));
|
|
5146
5476
|
};
|
|
5147
5477
|
handle.setAttribute("data-dragging", "true");
|
|
5148
5478
|
window.addEventListener("pointermove", onMove);
|
|
@@ -5154,34 +5484,28 @@ function createResizeHandle(options) {
|
|
|
5154
5484
|
if (pending === null) {
|
|
5155
5485
|
return;
|
|
5156
5486
|
}
|
|
5157
|
-
const
|
|
5487
|
+
const box = pending;
|
|
5158
5488
|
pending = null;
|
|
5159
|
-
options.commit(
|
|
5489
|
+
options.commit(box);
|
|
5160
5490
|
};
|
|
5161
5491
|
handle.addEventListener("keydown", (event) => {
|
|
5162
5492
|
const axis = options.axis();
|
|
5163
|
-
if (axis === "none") {
|
|
5493
|
+
if (axis === "none" || !movable(grip, axis)) {
|
|
5164
5494
|
return;
|
|
5165
5495
|
}
|
|
5166
|
-
const
|
|
5496
|
+
const step = event.shiftKey ? COARSE_STEP2 : STEP2;
|
|
5167
5497
|
const rect = options.rect();
|
|
5168
|
-
const
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
const height = rect.bottom - rect.top;
|
|
5172
|
-
let next = null;
|
|
5173
|
-
if (event.key === "ArrowLeft") {
|
|
5174
|
-
next = { width: Math.max(MIN_WIDTH, width - step * outward) };
|
|
5175
|
-
} else if (event.key === "ArrowRight") {
|
|
5176
|
-
next = { width: Math.max(MIN_WIDTH, width + step * outward) };
|
|
5177
|
-
} else if (axis === "both" && (event.key === "ArrowUp" || event.key === "ArrowDown")) {
|
|
5178
|
-
const grow = event.key === (anchor.y === "bottom" ? "ArrowUp" : "ArrowDown");
|
|
5179
|
-
next = { height: Math.max(MIN_HEIGHT, height + (grow ? step : -step)) };
|
|
5498
|
+
const delta = ARROWS[event.key];
|
|
5499
|
+
if (delta === void 0) {
|
|
5500
|
+
return;
|
|
5180
5501
|
}
|
|
5181
|
-
if (
|
|
5502
|
+
if (delta.x !== 0 && grip.x === void 0 || delta.y !== 0 && grip.y === void 0) {
|
|
5182
5503
|
return;
|
|
5183
5504
|
}
|
|
5184
5505
|
event.preventDefault();
|
|
5506
|
+
const x2 = (grip.x === "left" ? rect.left : rect.right) + delta.x * step;
|
|
5507
|
+
const y2 = (grip.y === "top" ? rect.top : rect.bottom) + delta.y * step;
|
|
5508
|
+
const next = boxAt(grip, axis, rect, x2, y2);
|
|
5185
5509
|
options.apply(next);
|
|
5186
5510
|
pending = next;
|
|
5187
5511
|
});
|
|
@@ -5189,6 +5513,26 @@ function createResizeHandle(options) {
|
|
|
5189
5513
|
handle.addEventListener("blur", settle);
|
|
5190
5514
|
return handle;
|
|
5191
5515
|
}
|
|
5516
|
+
var ARROWS = {
|
|
5517
|
+
ArrowLeft: { x: -1, y: 0 },
|
|
5518
|
+
ArrowRight: { x: 1, y: 0 },
|
|
5519
|
+
ArrowUp: { x: 0, y: -1 },
|
|
5520
|
+
ArrowDown: { x: 0, y: 1 }
|
|
5521
|
+
};
|
|
5522
|
+
function gripName(grip) {
|
|
5523
|
+
return [grip.y, grip.x].filter((side) => side !== void 0).join("-");
|
|
5524
|
+
}
|
|
5525
|
+
function movable(grip, axis) {
|
|
5526
|
+
return axis === "both" || grip.x !== void 0;
|
|
5527
|
+
}
|
|
5528
|
+
function boxAt(grip, axis, rect, x2, y2) {
|
|
5529
|
+
const left = grip.x === "left" ? Math.min(x2, rect.right - MIN_WIDTH) : rect.left;
|
|
5530
|
+
const right = grip.x === "right" ? Math.max(x2, rect.left + MIN_WIDTH) : rect.right;
|
|
5531
|
+
const vertical = axis === "both";
|
|
5532
|
+
const top = vertical && grip.y === "top" ? Math.min(y2, rect.bottom - MIN_HEIGHT) : rect.top;
|
|
5533
|
+
const bottom = vertical && grip.y === "bottom" ? Math.max(y2, rect.top + MIN_HEIGHT) : rect.bottom;
|
|
5534
|
+
return { left, top, right, bottom };
|
|
5535
|
+
}
|
|
5192
5536
|
|
|
5193
5537
|
// src/ui/reveal_words.ts
|
|
5194
5538
|
function collectTextNodes(root, out) {
|
|
@@ -5226,7 +5570,7 @@ function wrapWords(root) {
|
|
|
5226
5570
|
}
|
|
5227
5571
|
|
|
5228
5572
|
// src/ui/run_notice.ts
|
|
5229
|
-
function renderRunNotice(icon,
|
|
5573
|
+
function renderRunNotice(icon, text4, kind) {
|
|
5230
5574
|
const notice = document.createElement("div");
|
|
5231
5575
|
notice.className = `run-notice run-notice--${kind}`;
|
|
5232
5576
|
notice.setAttribute("part", `run-notice run-notice-${kind}`);
|
|
@@ -5239,7 +5583,7 @@ function renderRunNotice(icon, text3, kind) {
|
|
|
5239
5583
|
const label = document.createElement("span");
|
|
5240
5584
|
label.className = "run-notice-text";
|
|
5241
5585
|
label.setAttribute("part", "run-notice-text");
|
|
5242
|
-
label.textContent =
|
|
5586
|
+
label.textContent = text4;
|
|
5243
5587
|
notice.append(glyph, label);
|
|
5244
5588
|
return notice;
|
|
5245
5589
|
}
|
|
@@ -5495,6 +5839,30 @@ var STYLES = `
|
|
|
5495
5839
|
--_text: var(--ag-ui-text, var(--_fg));
|
|
5496
5840
|
--_surface: var(--ag-ui-surface, transparent);
|
|
5497
5841
|
|
|
5842
|
+
/* Message action row: the control box and the mark inside it. The box has a
|
|
5843
|
+
floor of 24px so it stays a reliable target at every density. */
|
|
5844
|
+
--_action-size: var(--ag-ui-action-size, 28px);
|
|
5845
|
+
--_action-icon-size: var(--ag-ui-action-icon-size, 15px);
|
|
5846
|
+
--_tooltip-bg: var(--ag-ui-tooltip-bg, #1f2430);
|
|
5847
|
+
--_tooltip-fg: var(--ag-ui-tooltip-fg, #f5f6fa);
|
|
5848
|
+
|
|
5849
|
+
/* Text and marks drawn on top of the accent and danger fills. Separate
|
|
5850
|
+
tokens because they are not free: a host that themes the accent to a pale
|
|
5851
|
+
colour has white-on-pale with no way to correct it, which is the one
|
|
5852
|
+
theming change that makes a control unreadable rather than merely off. */
|
|
5853
|
+
--_on-accent: var(--ag-ui-on-accent, #ffffff);
|
|
5854
|
+
--_on-danger: var(--ag-ui-on-danger, #ffffff);
|
|
5855
|
+
|
|
5856
|
+
/* Resize grips: the corner squares and the edge strips between them. Wide
|
|
5857
|
+
enough to hit without being wide enough to swallow a click on the content
|
|
5858
|
+
underneath, and adjustable for a host with a coarser pointer. */
|
|
5859
|
+
--_grip-corner: var(--ag-ui-grip-corner, 14px);
|
|
5860
|
+
--_grip-edge: var(--ag-ui-grip-edge, 6px);
|
|
5861
|
+
--_grip-edge-docked: var(--ag-ui-grip-edge-docked, 8px);
|
|
5862
|
+
/* The mark drawn inside a grip, as opposed to the area it answers to. */
|
|
5863
|
+
--_grip-mark-length: var(--ag-ui-grip-mark-length, 28px);
|
|
5864
|
+
--_grip-mark-thickness: var(--ag-ui-grip-mark-thickness, 3px);
|
|
5865
|
+
|
|
5498
5866
|
/* Status accents for tool-call cards. */
|
|
5499
5867
|
--_success: var(--ag-ui-success, #15803d);
|
|
5500
5868
|
--_danger: var(--ag-ui-danger, #b91c1c);
|
|
@@ -5505,6 +5873,12 @@ var STYLES = `
|
|
|
5505
5873
|
--_tool-icon-done: var(--ag-ui-tool-icon-done, "\u2713");
|
|
5506
5874
|
--_tool-icon-error: var(--ag-ui-tool-icon-error, "\u2715");
|
|
5507
5875
|
--_tool-icon-declined: var(--ag-ui-tool-icon-declined, "\u2298");
|
|
5876
|
+
|
|
5877
|
+
/* Disclosure marks on every expandable row. Tokenised for the same reason
|
|
5878
|
+
the status icons above are: a host re-theming one set and not the other
|
|
5879
|
+
ends up with two vocabularies in one transcript. */
|
|
5880
|
+
--_disclosure-collapsed: var(--ag-ui-disclosure-collapsed, "\u25B8");
|
|
5881
|
+
--_disclosure-expanded: var(--ag-ui-disclosure-expanded, "\u25BE");
|
|
5508
5882
|
--_tool-spin-duration: var(--ag-ui-tool-spin-duration, 0.7s);
|
|
5509
5883
|
|
|
5510
5884
|
/* Answer well (opt-in via data-answer-well) \u2014 boxes a whole assistant turn. */
|
|
@@ -5785,6 +6159,9 @@ var STYLES = `
|
|
|
5785
6159
|
font: inherit;
|
|
5786
6160
|
cursor: pointer;
|
|
5787
6161
|
pointer-events: auto;
|
|
6162
|
+
/* A touch drag on the launcher moves it; without this the page scrolls under
|
|
6163
|
+
the finger instead and the launcher never moves at all. */
|
|
6164
|
+
touch-action: none;
|
|
5788
6165
|
opacity: 0;
|
|
5789
6166
|
transform: scale(0.4);
|
|
5790
6167
|
visibility: hidden;
|
|
@@ -5814,6 +6191,15 @@ var STYLES = `
|
|
|
5814
6191
|
transform: scale(0.94);
|
|
5815
6192
|
}
|
|
5816
6193
|
|
|
6194
|
+
/* A drag is a press and a hover at the same time, so both scale rules above are
|
|
6195
|
+
live throughout it. Cancelling them is what keeps the launcher the size of
|
|
6196
|
+
the thing under the pointer while it travels; the position itself comes from
|
|
6197
|
+
inset, which nothing here transitions, so it tracks the pointer exactly. */
|
|
6198
|
+
:host([collapsed]) .launcher[data-dragging] {
|
|
6199
|
+
transform: none;
|
|
6200
|
+
cursor: grabbing;
|
|
6201
|
+
}
|
|
6202
|
+
|
|
5817
6203
|
.launcher .icon-holder {
|
|
5818
6204
|
width: var(--_launcher-icon-size);
|
|
5819
6205
|
height: var(--_launcher-icon-size);
|
|
@@ -6008,6 +6394,31 @@ var STYLES = `
|
|
|
6008
6394
|
transform-origin: bottom left;
|
|
6009
6395
|
}
|
|
6010
6396
|
|
|
6397
|
+
/* Once the launcher has been dragged the element places itself, and stamps the
|
|
6398
|
+
corner it chose to open away from. The morph has to start at that same
|
|
6399
|
+
corner: scaling out of the one the placement originally guessed reads as the
|
|
6400
|
+
panel leaping across the screen before it opens.
|
|
6401
|
+
|
|
6402
|
+
Equal specificity to the placement rule above, so source order is what lets
|
|
6403
|
+
the stamped value win -- the same arrangement the resize grip uses, and the
|
|
6404
|
+
same trap. Write these with = on the whole hyphenated token; a ~= would match
|
|
6405
|
+
whitespace-separated words and so could never match at all. */
|
|
6406
|
+
:host([data-expand-corner="top-left"]) .chat {
|
|
6407
|
+
transform-origin: top left;
|
|
6408
|
+
}
|
|
6409
|
+
|
|
6410
|
+
:host([data-expand-corner="top-right"]) .chat {
|
|
6411
|
+
transform-origin: top right;
|
|
6412
|
+
}
|
|
6413
|
+
|
|
6414
|
+
:host([data-expand-corner="bottom-left"]) .chat {
|
|
6415
|
+
transform-origin: bottom left;
|
|
6416
|
+
}
|
|
6417
|
+
|
|
6418
|
+
:host([data-expand-corner="bottom-right"]) .chat {
|
|
6419
|
+
transform-origin: bottom right;
|
|
6420
|
+
}
|
|
6421
|
+
|
|
6011
6422
|
/* The two in-flow placements keep the original collapse: hide the body, let
|
|
6012
6423
|
the host shrink to the header bar. */
|
|
6013
6424
|
:host([collapsed]:is([placement="embedded"], [placement="page"])) {
|
|
@@ -6191,7 +6602,22 @@ var STYLES = `
|
|
|
6191
6602
|
border-radius: var(--_msg-radius);
|
|
6192
6603
|
line-height: 1.4;
|
|
6193
6604
|
white-space: pre-wrap;
|
|
6194
|
-
word-break
|
|
6605
|
+
/* overflow-wrap, not word-break, and the difference is the whole reason a
|
|
6606
|
+
markdown table used to be unreadable.
|
|
6607
|
+
|
|
6608
|
+
Both stop one long unbroken token blowing out the bubble, which is all this
|
|
6609
|
+
is for. But word-break: break-word is the legacy spelling of "break
|
|
6610
|
+
anywhere", and breaking anywhere drops the *min-content* width of every
|
|
6611
|
+
descendant to one character. A table's column algorithm takes min-content
|
|
6612
|
+
as an input, so the table always fitted max-width: 100%, the overflow-x:
|
|
6613
|
+
auto below it never had anything to scroll, and the columns absorbed the
|
|
6614
|
+
pressure by rendering one letter per line instead. A seven-column header
|
|
6615
|
+
came out 162px tall.
|
|
6616
|
+
|
|
6617
|
+
overflow-wrap: break-word breaks a word only when it would otherwise
|
|
6618
|
+
overflow its line, and leaves min-content alone -- so the bubble is still
|
|
6619
|
+
protected and the table is free to be wider than the panel and scroll. */
|
|
6620
|
+
overflow-wrap: break-word;
|
|
6195
6621
|
}
|
|
6196
6622
|
|
|
6197
6623
|
/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
@@ -6433,11 +6859,11 @@ var STYLES = `
|
|
|
6433
6859
|
}
|
|
6434
6860
|
|
|
6435
6861
|
.thoughts-toggle::before {
|
|
6436
|
-
content: "
|
|
6862
|
+
content: var(--_disclosure-expanded) " ";
|
|
6437
6863
|
}
|
|
6438
6864
|
|
|
6439
6865
|
.thoughts-toggle[aria-expanded="false"]::before {
|
|
6440
|
-
content: "
|
|
6866
|
+
content: var(--_disclosure-collapsed) " ";
|
|
6441
6867
|
}
|
|
6442
6868
|
|
|
6443
6869
|
/* A gentle pulse on the label while reasoning is still streaming. */
|
|
@@ -6779,14 +7205,14 @@ var STYLES = `
|
|
|
6779
7205
|
}
|
|
6780
7206
|
|
|
6781
7207
|
.subagent-row::after {
|
|
6782
|
-
content:
|
|
7208
|
+
content: var(--_disclosure-collapsed);
|
|
6783
7209
|
flex: none;
|
|
6784
7210
|
margin-left: auto;
|
|
6785
7211
|
color: var(--_accent);
|
|
6786
7212
|
}
|
|
6787
7213
|
|
|
6788
7214
|
.subagent-row[aria-expanded="true"]::after {
|
|
6789
|
-
content:
|
|
7215
|
+
content: var(--_disclosure-expanded);
|
|
6790
7216
|
}
|
|
6791
7217
|
|
|
6792
7218
|
.subagent-row:disabled::after {
|
|
@@ -6913,16 +7339,23 @@ var STYLES = `
|
|
|
6913
7339
|
}
|
|
6914
7340
|
|
|
6915
7341
|
.tool-call-toggle::before {
|
|
6916
|
-
content: "
|
|
7342
|
+
content: var(--_disclosure-collapsed) " ";
|
|
6917
7343
|
}
|
|
6918
7344
|
|
|
6919
7345
|
.tool-call-toggle[aria-expanded="true"]::before {
|
|
6920
|
-
content: "
|
|
7346
|
+
content: var(--_disclosure-expanded) " ";
|
|
6921
7347
|
}
|
|
6922
7348
|
|
|
6923
|
-
/* Resize
|
|
6924
|
-
|
|
6925
|
-
nothing to drag.
|
|
7349
|
+
/* Resize grips: every edge and every corner, so the panel can be dragged from
|
|
7350
|
+
whichever side the reader is already near. Absent entirely where the
|
|
7351
|
+
placement is full-bleed, since there is nothing to drag.
|
|
7352
|
+
|
|
7353
|
+
The whole set is always laid out. Which edges the *layout* pins is not a
|
|
7354
|
+
question the stylesheet needs to answer any more -- it decided where the one
|
|
7355
|
+
grip went, and there is no longer one grip. The element still measures and
|
|
7356
|
+
stamps data-resize-anchor, because it decides what a drag on a pinned edge
|
|
7357
|
+
costs in position and which grip carries the tab stop, but no rule here
|
|
7358
|
+
reads it. */
|
|
6926
7359
|
.resize-handle {
|
|
6927
7360
|
position: absolute;
|
|
6928
7361
|
z-index: 2;
|
|
@@ -6935,95 +7368,102 @@ var STYLES = `
|
|
|
6935
7368
|
outline-offset: -2px;
|
|
6936
7369
|
}
|
|
6937
7370
|
|
|
6938
|
-
/*
|
|
6939
|
-
|
|
7371
|
+
/* Corners first in the file and last in the DOM, so they take the pointer
|
|
7372
|
+
where they overlap an edge strip. */
|
|
7373
|
+
.resize-handle--top-left,
|
|
7374
|
+
.resize-handle--top-right,
|
|
7375
|
+
.resize-handle--bottom-left,
|
|
7376
|
+
.resize-handle--bottom-right {
|
|
7377
|
+
width: var(--_grip-corner);
|
|
7378
|
+
height: var(--_grip-corner);
|
|
7379
|
+
}
|
|
6940
7380
|
|
|
6941
|
-
|
|
6942
|
-
.resize-handle {
|
|
7381
|
+
.resize-handle--top-left {
|
|
6943
7382
|
top: 0;
|
|
6944
7383
|
left: 0;
|
|
6945
|
-
width: 14px;
|
|
6946
|
-
height: 14px;
|
|
6947
7384
|
cursor: nwse-resize;
|
|
6948
7385
|
}
|
|
6949
7386
|
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
bottom-left is pinned there, so its free corner is top-right. */
|
|
6953
|
-
:host([placement="embedded"]) .resize-handle {
|
|
6954
|
-
top: auto;
|
|
6955
|
-
left: auto;
|
|
7387
|
+
.resize-handle--top-right {
|
|
7388
|
+
top: 0;
|
|
6956
7389
|
right: 0;
|
|
6957
|
-
|
|
6958
|
-
cursor: nwse-resize;
|
|
7390
|
+
cursor: nesw-resize;
|
|
6959
7391
|
}
|
|
6960
7392
|
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
7393
|
+
.resize-handle--bottom-left {
|
|
7394
|
+
bottom: 0;
|
|
7395
|
+
left: 0;
|
|
6964
7396
|
cursor: nesw-resize;
|
|
6965
7397
|
}
|
|
6966
7398
|
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
anchored bottom-left -- so the element measures them and stamps a single
|
|
6970
|
-
hyphenated "<y>-<x>" token here. Equal specificity to the rules above, so
|
|
6971
|
-
source order is what lets the measured value win.
|
|
6972
|
-
|
|
6973
|
-
Two traps, both of which silently draw the grip on the corner that moves:
|
|
6974
|
-
|
|
6975
|
-
Never write these as [data-resize-anchor~="left"]. The stamped value is one
|
|
6976
|
-
hyphenated token and ~= matches whitespace-separated words, so it can never
|
|
6977
|
-
match.
|
|
6978
|
-
|
|
6979
|
-
Each rule must set both sides of its axis, not only the side it moves, or it
|
|
6980
|
-
cannot undo a placement guess that flipped the other way. */
|
|
6981
|
-
:host([data-resize-anchor$="-left"]) .resize-handle {
|
|
6982
|
-
left: auto;
|
|
7399
|
+
.resize-handle--bottom-right {
|
|
7400
|
+
bottom: 0;
|
|
6983
7401
|
right: 0;
|
|
7402
|
+
cursor: nwse-resize;
|
|
6984
7403
|
}
|
|
6985
7404
|
|
|
6986
|
-
|
|
7405
|
+
/* Edge strips, held clear of the corners at both ends so a corner drag is
|
|
7406
|
+
never swallowed by the edge next to it. */
|
|
7407
|
+
.resize-handle--left,
|
|
7408
|
+
.resize-handle--right {
|
|
7409
|
+
top: var(--_grip-corner);
|
|
7410
|
+
bottom: var(--_grip-corner);
|
|
7411
|
+
width: var(--_grip-edge);
|
|
7412
|
+
cursor: ew-resize;
|
|
7413
|
+
}
|
|
7414
|
+
|
|
7415
|
+
.resize-handle--left {
|
|
6987
7416
|
left: 0;
|
|
6988
|
-
right: auto;
|
|
6989
7417
|
}
|
|
6990
7418
|
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
bottom: 0;
|
|
7419
|
+
.resize-handle--right {
|
|
7420
|
+
right: 0;
|
|
6994
7421
|
}
|
|
6995
7422
|
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
7423
|
+
.resize-handle--top,
|
|
7424
|
+
.resize-handle--bottom {
|
|
7425
|
+
left: var(--_grip-corner);
|
|
7426
|
+
right: var(--_grip-corner);
|
|
7427
|
+
height: var(--_grip-edge);
|
|
7428
|
+
cursor: ns-resize;
|
|
6999
7429
|
}
|
|
7000
7430
|
|
|
7001
|
-
|
|
7002
|
-
:
|
|
7003
|
-
:host([data-resize-anchor="bottom-right"]) .resize-handle {
|
|
7004
|
-
cursor: nwse-resize;
|
|
7431
|
+
.resize-handle--top {
|
|
7432
|
+
top: 0;
|
|
7005
7433
|
}
|
|
7006
7434
|
|
|
7007
|
-
|
|
7008
|
-
:
|
|
7009
|
-
cursor: nesw-resize;
|
|
7435
|
+
.resize-handle--bottom {
|
|
7436
|
+
bottom: 0;
|
|
7010
7437
|
}
|
|
7011
7438
|
|
|
7012
|
-
/* Docked: the placement owns the height, so
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7439
|
+
/* Docked: the placement owns the height, so the horizontal edges and every
|
|
7440
|
+
corner are inert and must not advertise a drag that does nothing. The two
|
|
7441
|
+
vertical edges remain, which is the same affordance these placements had
|
|
7442
|
+
when there was one grip -- now on both sides, since either may be the inner
|
|
7443
|
+
one depending on which side the rail is docked to. */
|
|
7444
|
+
:host([placement="sidebar"]) .resize-handle--top,
|
|
7445
|
+
:host([placement="sidebar"]) .resize-handle--bottom,
|
|
7446
|
+
:host([placement="sidebar"]) .resize-handle--top-left,
|
|
7447
|
+
:host([placement="sidebar"]) .resize-handle--top-right,
|
|
7448
|
+
:host([placement="sidebar"]) .resize-handle--bottom-left,
|
|
7449
|
+
:host([placement="sidebar"]) .resize-handle--bottom-right,
|
|
7450
|
+
:host([placement="side"]) .resize-handle--top,
|
|
7451
|
+
:host([placement="side"]) .resize-handle--bottom,
|
|
7452
|
+
:host([placement="side"]) .resize-handle--top-left,
|
|
7453
|
+
:host([placement="side"]) .resize-handle--top-right,
|
|
7454
|
+
:host([placement="side"]) .resize-handle--bottom-left,
|
|
7455
|
+
:host([placement="side"]) .resize-handle--bottom-right {
|
|
7456
|
+
display: none;
|
|
7021
7457
|
}
|
|
7022
7458
|
|
|
7023
|
-
/*
|
|
7024
|
-
:host([placement="sidebar"]
|
|
7025
|
-
|
|
7026
|
-
|
|
7459
|
+
/* The vertical edges run the full height once no corner shares them. */
|
|
7460
|
+
:host([placement="sidebar"]) .resize-handle--left,
|
|
7461
|
+
:host([placement="sidebar"]) .resize-handle--right,
|
|
7462
|
+
:host([placement="side"]) .resize-handle--left,
|
|
7463
|
+
:host([placement="side"]) .resize-handle--right {
|
|
7464
|
+
top: 0;
|
|
7465
|
+
bottom: 0;
|
|
7466
|
+
width: var(--_grip-edge-docked);
|
|
7027
7467
|
}
|
|
7028
7468
|
|
|
7029
7469
|
/* Full-bleed: nothing to drag. */
|
|
@@ -7032,9 +7472,62 @@ var STYLES = `
|
|
|
7032
7472
|
display: none;
|
|
7033
7473
|
}
|
|
7034
7474
|
|
|
7035
|
-
.
|
|
7475
|
+
/* The visible mark on a grip.
|
|
7476
|
+
|
|
7477
|
+
Filling the whole strip was what the single corner grip did, and at 14px
|
|
7478
|
+
square nobody ever saw it. On a strip running the length of an edge the same
|
|
7479
|
+
fill reads as a border the panel grew -- square ended, stopping short of the
|
|
7480
|
+
corner radius at both ends, and easily mistaken for a rendering fault rather
|
|
7481
|
+
than for something to grab.
|
|
7482
|
+
|
|
7483
|
+
So the hit area stays the full strip and the mark is a short pill centred on
|
|
7484
|
+
it, which cannot be read as an edge of anything and never meets the radius.
|
|
7485
|
+
|
|
7486
|
+
It shows on hover and focus as well as during the drag. With eight grips, a
|
|
7487
|
+
mark that appears only once you are already dragging is a mark that never
|
|
7488
|
+
told anyone the grips were there. */
|
|
7489
|
+
.resize-handle::after {
|
|
7490
|
+
content: "";
|
|
7491
|
+
position: absolute;
|
|
7492
|
+
top: 50%;
|
|
7493
|
+
left: 50%;
|
|
7494
|
+
transform: translate(-50%, -50%);
|
|
7495
|
+
border-radius: 999px;
|
|
7036
7496
|
background: var(--_accent);
|
|
7037
|
-
opacity: 0
|
|
7497
|
+
opacity: 0;
|
|
7498
|
+
transition: opacity var(--_motion) var(--_ease);
|
|
7499
|
+
}
|
|
7500
|
+
|
|
7501
|
+
.resize-handle--top::after,
|
|
7502
|
+
.resize-handle--bottom::after {
|
|
7503
|
+
width: var(--_grip-mark-length);
|
|
7504
|
+
height: var(--_grip-mark-thickness);
|
|
7505
|
+
}
|
|
7506
|
+
|
|
7507
|
+
.resize-handle--left::after,
|
|
7508
|
+
.resize-handle--right::after {
|
|
7509
|
+
width: var(--_grip-mark-thickness);
|
|
7510
|
+
height: var(--_grip-mark-length);
|
|
7511
|
+
}
|
|
7512
|
+
|
|
7513
|
+
/* A corner has no length to run along, so it gets a dot instead of a pill. */
|
|
7514
|
+
.resize-handle--top-left::after,
|
|
7515
|
+
.resize-handle--top-right::after,
|
|
7516
|
+
.resize-handle--bottom-left::after,
|
|
7517
|
+
.resize-handle--bottom-right::after {
|
|
7518
|
+
width: var(--_grip-mark-thickness);
|
|
7519
|
+
height: var(--_grip-mark-thickness);
|
|
7520
|
+
}
|
|
7521
|
+
|
|
7522
|
+
.resize-handle:hover::after,
|
|
7523
|
+
.resize-handle:focus-visible::after {
|
|
7524
|
+
opacity: 0.5;
|
|
7525
|
+
}
|
|
7526
|
+
|
|
7527
|
+
/* Equal specificity to the pair above, so source order is what makes the drag
|
|
7528
|
+
the stronger of the two states. */
|
|
7529
|
+
.resize-handle[data-dragging]::after {
|
|
7530
|
+
opacity: 0.9;
|
|
7038
7531
|
}
|
|
7039
7532
|
|
|
7040
7533
|
/* \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -7148,7 +7641,7 @@ var STYLES = `
|
|
|
7148
7641
|
border: none;
|
|
7149
7642
|
border-radius: 50%;
|
|
7150
7643
|
background: var(--_accent);
|
|
7151
|
-
color:
|
|
7644
|
+
color: var(--_on-accent);
|
|
7152
7645
|
font: inherit;
|
|
7153
7646
|
line-height: 1;
|
|
7154
7647
|
cursor: pointer;
|
|
@@ -7222,13 +7715,13 @@ var STYLES = `
|
|
|
7222
7715
|
/* Recording: a red tint + a gentle pulse so it's clearly "live". */
|
|
7223
7716
|
.voice-btn[data-state="recording"] {
|
|
7224
7717
|
background: var(--_danger);
|
|
7225
|
-
color:
|
|
7718
|
+
color: var(--_on-danger);
|
|
7226
7719
|
animation: ag-ui-voice-pulse 1.2s ease-in-out infinite;
|
|
7227
7720
|
}
|
|
7228
7721
|
|
|
7229
7722
|
.voice-btn[data-state="recording"]:hover {
|
|
7230
7723
|
background: var(--_danger);
|
|
7231
|
-
color:
|
|
7724
|
+
color: var(--_on-danger);
|
|
7232
7725
|
}
|
|
7233
7726
|
|
|
7234
7727
|
@keyframes ag-ui-voice-pulse {
|
|
@@ -7518,7 +8011,7 @@ var STYLES = `
|
|
|
7518
8011
|
.confirm-btn--confirm {
|
|
7519
8012
|
border-color: var(--_accent);
|
|
7520
8013
|
background: var(--_accent);
|
|
7521
|
-
color:
|
|
8014
|
+
color: var(--_on-accent);
|
|
7522
8015
|
}
|
|
7523
8016
|
|
|
7524
8017
|
/* The session waiver. Deliberately the quietest of the three: it is the widest
|
|
@@ -7586,16 +8079,29 @@ var STYLES = `
|
|
|
7586
8079
|
margin-top: -6px;
|
|
7587
8080
|
}
|
|
7588
8081
|
|
|
8082
|
+
/* The row's controls are icon-only, so the box is the whole target. Sized from
|
|
8083
|
+
a variable a host can raise, with a floor rather than a fixed height: the
|
|
8084
|
+
compact density shrinks the font, and a target that shrinks with it lands
|
|
8085
|
+
under the 24px minimum that makes a control reliably tappable. It used to,
|
|
8086
|
+
at roughly 20px square. */
|
|
7589
8087
|
.message-action {
|
|
8088
|
+
display: inline-flex;
|
|
8089
|
+
align-items: center;
|
|
8090
|
+
justify-content: center;
|
|
8091
|
+
box-sizing: border-box;
|
|
8092
|
+
min-width: var(--_action-size);
|
|
8093
|
+
min-height: var(--_action-size);
|
|
8094
|
+
padding: 4px;
|
|
7590
8095
|
border: none;
|
|
7591
8096
|
border-radius: 6px;
|
|
7592
|
-
padding: 2px 6px;
|
|
7593
8097
|
font: inherit;
|
|
7594
8098
|
line-height: 1.2;
|
|
7595
8099
|
cursor: pointer;
|
|
7596
8100
|
background: transparent;
|
|
7597
8101
|
color: var(--_muted);
|
|
7598
8102
|
opacity: 0.75;
|
|
8103
|
+
/* The tooltip below is positioned against this box. */
|
|
8104
|
+
position: relative;
|
|
7599
8105
|
}
|
|
7600
8106
|
|
|
7601
8107
|
.message-action:hover,
|
|
@@ -7604,6 +8110,61 @@ var STYLES = `
|
|
|
7604
8110
|
background: var(--_border);
|
|
7605
8111
|
}
|
|
7606
8112
|
|
|
8113
|
+
.message-action-icon {
|
|
8114
|
+
display: inline-flex;
|
|
8115
|
+
width: var(--_action-icon-size);
|
|
8116
|
+
height: var(--_action-icon-size);
|
|
8117
|
+
}
|
|
8118
|
+
|
|
8119
|
+
.message-action-icon .glyph {
|
|
8120
|
+
width: 100%;
|
|
8121
|
+
height: 100%;
|
|
8122
|
+
}
|
|
8123
|
+
|
|
8124
|
+
/* The label, drawn rather than left to the browser.
|
|
8125
|
+
|
|
8126
|
+
A title attribute is the usual answer and covers only half the readers: it
|
|
8127
|
+
never appears on keyboard focus, so tabbing onto an icon-only control shows
|
|
8128
|
+
nothing at all. The attribute stays for the pointer users who expect it, and
|
|
8129
|
+
this shows the same words on hover and on focus alike.
|
|
8130
|
+
|
|
8131
|
+
Left-aligned rather than centred because the row sits at the left edge of an
|
|
8132
|
+
answer inside a scrolling column, and a centred tooltip on the first control
|
|
8133
|
+
is clipped by that column. Growing rightward keeps it inside.
|
|
8134
|
+
|
|
8135
|
+
Not exposed to assistive technology: the button already carries the same
|
|
8136
|
+
string as its accessible name, and this would be a second copy of it. */
|
|
8137
|
+
.message-action::after {
|
|
8138
|
+
content: attr(data-tooltip);
|
|
8139
|
+
position: absolute;
|
|
8140
|
+
bottom: calc(100% + 4px);
|
|
8141
|
+
left: 0;
|
|
8142
|
+
z-index: 3;
|
|
8143
|
+
padding: 3px 6px;
|
|
8144
|
+
border-radius: 4px;
|
|
8145
|
+
background: var(--_tooltip-bg);
|
|
8146
|
+
color: var(--_tooltip-fg);
|
|
8147
|
+
font-size: 11px;
|
|
8148
|
+
line-height: 1.4;
|
|
8149
|
+
white-space: nowrap;
|
|
8150
|
+
pointer-events: none;
|
|
8151
|
+
opacity: 0;
|
|
8152
|
+
transition: opacity var(--_motion) var(--_ease);
|
|
8153
|
+
}
|
|
8154
|
+
|
|
8155
|
+
.message-action:hover::after,
|
|
8156
|
+
.message-action:focus-visible::after {
|
|
8157
|
+
opacity: 1;
|
|
8158
|
+
}
|
|
8159
|
+
|
|
8160
|
+
/* Touch has no hover to reveal it, and a tooltip that latches open under a
|
|
8161
|
+
finger covers the answer it belongs to. */
|
|
8162
|
+
@media (hover: none) {
|
|
8163
|
+
.message-action::after {
|
|
8164
|
+
content: none;
|
|
8165
|
+
}
|
|
8166
|
+
}
|
|
8167
|
+
|
|
7607
8168
|
.message-action[aria-pressed="true"] {
|
|
7608
8169
|
opacity: 1;
|
|
7609
8170
|
color: var(--_accent);
|
|
@@ -7661,7 +8222,7 @@ var STYLES = `
|
|
|
7661
8222
|
.approval-btn--approve {
|
|
7662
8223
|
border-color: var(--_accent);
|
|
7663
8224
|
background: var(--_accent);
|
|
7664
|
-
color:
|
|
8225
|
+
color: var(--_on-accent);
|
|
7665
8226
|
}
|
|
7666
8227
|
|
|
7667
8228
|
/* Question card \u2014 the built-in ask_user prompt (radios and/or free text). */
|
|
@@ -7727,7 +8288,7 @@ var STYLES = `
|
|
|
7727
8288
|
font-weight: 600;
|
|
7728
8289
|
cursor: pointer;
|
|
7729
8290
|
background: var(--_accent);
|
|
7730
|
-
color:
|
|
8291
|
+
color: var(--_on-accent);
|
|
7731
8292
|
}
|
|
7732
8293
|
|
|
7733
8294
|
.question-btn:disabled {
|
|
@@ -7996,7 +8557,7 @@ var STYLES = `
|
|
|
7996
8557
|
font-weight: 600;
|
|
7997
8558
|
border-color: var(--_accent);
|
|
7998
8559
|
background: var(--_accent);
|
|
7999
|
-
color:
|
|
8560
|
+
color: var(--_on-accent);
|
|
8000
8561
|
}
|
|
8001
8562
|
|
|
8002
8563
|
.checkpoint-fork:hover {
|
|
@@ -8171,7 +8732,7 @@ var STYLES = `
|
|
|
8171
8732
|
border: none;
|
|
8172
8733
|
border-radius: 6px;
|
|
8173
8734
|
background: var(--_danger);
|
|
8174
|
-
color:
|
|
8735
|
+
color: var(--_on-danger);
|
|
8175
8736
|
padding: 3px 10px;
|
|
8176
8737
|
font: inherit;
|
|
8177
8738
|
cursor: pointer;
|
|
@@ -8748,11 +9309,11 @@ function resultLabels(strings) {
|
|
|
8748
9309
|
[TOOL_CALL_STATUS.DECLINED]: strings.declinedLabel
|
|
8749
9310
|
};
|
|
8750
9311
|
}
|
|
8751
|
-
function formatPayload(
|
|
9312
|
+
function formatPayload(text4) {
|
|
8752
9313
|
try {
|
|
8753
|
-
return JSON.stringify(JSON.parse(
|
|
9314
|
+
return JSON.stringify(JSON.parse(text4), null, 2);
|
|
8754
9315
|
} catch {
|
|
8755
|
-
return
|
|
9316
|
+
return text4;
|
|
8756
9317
|
}
|
|
8757
9318
|
}
|
|
8758
9319
|
var ToolCallCard = class {
|
|
@@ -8901,7 +9462,7 @@ var ToolCallCard = class {
|
|
|
8901
9462
|
* Flip the status pill to `status` and fill in the result region, whose
|
|
8902
9463
|
* heading names the outcome (result / error / declined).
|
|
8903
9464
|
*/
|
|
8904
|
-
settle(status,
|
|
9465
|
+
settle(status, text4) {
|
|
8905
9466
|
if (this.#settled) {
|
|
8906
9467
|
return;
|
|
8907
9468
|
}
|
|
@@ -8911,8 +9472,8 @@ var ToolCallCard = class {
|
|
|
8911
9472
|
this.#resultLabel.textContent = resultLabels(this.#strings)[status];
|
|
8912
9473
|
this.#renderPayload(
|
|
8913
9474
|
this.#resultBody,
|
|
8914
|
-
{ kind: "result", toolName: this.#name, status, text:
|
|
8915
|
-
formatPayload(
|
|
9475
|
+
{ kind: "result", toolName: this.#name, status, text: text4 },
|
|
9476
|
+
formatPayload(text4)
|
|
8916
9477
|
);
|
|
8917
9478
|
this.#resultSection.hidden = false;
|
|
8918
9479
|
}
|
|
@@ -9072,7 +9633,7 @@ var VoiceInput = class {
|
|
|
9072
9633
|
this.#setState("transcribing");
|
|
9073
9634
|
const audio = new Blob(this.#chunks, { type: mimeType || "audio/webm" });
|
|
9074
9635
|
try {
|
|
9075
|
-
const
|
|
9636
|
+
const text4 = await this.#transcribe(audio);
|
|
9076
9637
|
this.#setState("idle");
|
|
9077
9638
|
if (this.#hitCap) {
|
|
9078
9639
|
this.element.title = this.#strings.recordingLimit.replace(
|
|
@@ -9080,8 +9641,8 @@ var VoiceInput = class {
|
|
|
9080
9641
|
String(MAX_RECORDING_MS / 6e4)
|
|
9081
9642
|
);
|
|
9082
9643
|
}
|
|
9083
|
-
if (
|
|
9084
|
-
this.#onText(
|
|
9644
|
+
if (text4 !== "") {
|
|
9645
|
+
this.#onText(text4);
|
|
9085
9646
|
}
|
|
9086
9647
|
} catch (error) {
|
|
9087
9648
|
this.#fail(error instanceof Error ? error.message : this.#strings.transcriptionFailed);
|
|
@@ -9711,9 +10272,9 @@ function isOwnedSuffix(suffix) {
|
|
|
9711
10272
|
function deriveTitle(messages) {
|
|
9712
10273
|
for (const message of messages) {
|
|
9713
10274
|
if (message.role === "user") {
|
|
9714
|
-
const
|
|
9715
|
-
if (
|
|
9716
|
-
return truncate(
|
|
10275
|
+
const text4 = cleanText(message.content);
|
|
10276
|
+
if (text4 !== "") {
|
|
10277
|
+
return truncate(text4, TITLE_LIMIT);
|
|
9717
10278
|
}
|
|
9718
10279
|
}
|
|
9719
10280
|
}
|
|
@@ -9721,9 +10282,9 @@ function deriveTitle(messages) {
|
|
|
9721
10282
|
}
|
|
9722
10283
|
function derivePreview(messages) {
|
|
9723
10284
|
for (const message of [...messages].reverse()) {
|
|
9724
|
-
const
|
|
9725
|
-
if (
|
|
9726
|
-
return truncate(
|
|
10285
|
+
const text4 = cleanText(message.content);
|
|
10286
|
+
if (text4 !== "") {
|
|
10287
|
+
return truncate(text4, PREVIEW_LIMIT);
|
|
9727
10288
|
}
|
|
9728
10289
|
}
|
|
9729
10290
|
return "";
|
|
@@ -9731,8 +10292,8 @@ function derivePreview(messages) {
|
|
|
9731
10292
|
function cleanText(content) {
|
|
9732
10293
|
return typeof content === "string" ? content.replace(/\s+/g, " ").trim() : "";
|
|
9733
10294
|
}
|
|
9734
|
-
function truncate(
|
|
9735
|
-
return
|
|
10295
|
+
function truncate(text4, limit) {
|
|
10296
|
+
return text4.length <= limit ? text4 : `${text4.slice(0, limit - 1).trimEnd()}\u2026`;
|
|
9736
10297
|
}
|
|
9737
10298
|
|
|
9738
10299
|
// src/core/create_http_agent.ts
|
|
@@ -10136,6 +10697,18 @@ function isCredentialsMode(value) {
|
|
|
10136
10697
|
var COLLAPSED_KEY = "ag-ui-chat:collapsed";
|
|
10137
10698
|
var SIZE_KEY = "ag-ui-chat:size";
|
|
10138
10699
|
var THEME_KEY = "ag-ui-chat:theme";
|
|
10700
|
+
var LAUNCHER_KEY = "ag-ui-chat:launcher";
|
|
10701
|
+
var DRAGGABLE_PLACEMENTS = /* @__PURE__ */ new Set([null, "", "floating", "bottom-left"]);
|
|
10702
|
+
var RESIZE_GRIPS = [
|
|
10703
|
+
{ y: "top" },
|
|
10704
|
+
{ y: "bottom" },
|
|
10705
|
+
{ x: "left" },
|
|
10706
|
+
{ x: "right" },
|
|
10707
|
+
{ x: "left", y: "top" },
|
|
10708
|
+
{ x: "right", y: "top" },
|
|
10709
|
+
{ x: "left", y: "bottom" },
|
|
10710
|
+
{ x: "right", y: "bottom" }
|
|
10711
|
+
];
|
|
10139
10712
|
var QUOTE_GAP = 6;
|
|
10140
10713
|
var CLAIMED_NAMESPACES = /* @__PURE__ */ new Set();
|
|
10141
10714
|
var AgUiChat = class extends HTMLElement {
|
|
@@ -10547,6 +11120,32 @@ var AgUiChat = class extends HTMLElement {
|
|
|
10547
11120
|
#emptyWrap;
|
|
10548
11121
|
/** Upload tray; created on connect only when `data-attachments-url` is set. */
|
|
10549
11122
|
#attachTray = null;
|
|
11123
|
+
/**
|
|
11124
|
+
* Where the user dragged the launcher, in viewport coordinates, or null
|
|
11125
|
+
* while the host's own CSS still places it. Set means this element owns its
|
|
11126
|
+
* position -- see #applyLauncherPlacement for what that costs the host.
|
|
11127
|
+
*/
|
|
11128
|
+
#launcherPos = null;
|
|
11129
|
+
/**
|
|
11130
|
+
* The corner the panel opens away from, once this element is placing itself.
|
|
11131
|
+
* Null means the host's layout still decides, and the anchor is measured.
|
|
11132
|
+
*/
|
|
11133
|
+
#expandCorner = null;
|
|
11134
|
+
/**
|
|
11135
|
+
* The edges the layout is holding still, as last measured. Cached because a
|
|
11136
|
+
* resize reads it per pointer move and measuring forces a reflow -- thirty a
|
|
11137
|
+
* second while the panel is already being laid out on every one of them.
|
|
11138
|
+
*/
|
|
11139
|
+
#anchor = { x: "right", y: "bottom" };
|
|
11140
|
+
/** The eight grips, by name, so the keyboard-reachable one can be moved. */
|
|
11141
|
+
#resizeHandles = /* @__PURE__ */ new Map();
|
|
11142
|
+
/**
|
|
11143
|
+
* Re-clamp the dragged launcher when the window changes size. Bound once as
|
|
11144
|
+
* a field so `removeEventListener` on disconnect gets the same reference.
|
|
11145
|
+
*/
|
|
11146
|
+
#onViewportResize = () => {
|
|
11147
|
+
this.#restoreLauncherPosition();
|
|
11148
|
+
};
|
|
10550
11149
|
/** Mic button mount point (input row); the control mounts on connect when enabled. */
|
|
10551
11150
|
#voiceSlot;
|
|
10552
11151
|
/** Voice-input control; created on connect when transcription is available. */
|
|
@@ -10755,6 +11354,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
10755
11354
|
}
|
|
10756
11355
|
if (name === "placement") {
|
|
10757
11356
|
this.#releaseOwnedAxes();
|
|
11357
|
+
this.#releaseLauncherPosition();
|
|
10758
11358
|
requestAnimationFrame(() => this.#syncResizeAnchor());
|
|
10759
11359
|
return;
|
|
10760
11360
|
}
|
|
@@ -11102,7 +11702,10 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11102
11702
|
connectedCallback() {
|
|
11103
11703
|
this.#storageNs = this.#claimNamespace();
|
|
11104
11704
|
this.#applySize(this.#readSize());
|
|
11105
|
-
requestAnimationFrame(() =>
|
|
11705
|
+
requestAnimationFrame(() => {
|
|
11706
|
+
this.#restoreLauncherPosition();
|
|
11707
|
+
this.#syncResizeAnchor();
|
|
11708
|
+
});
|
|
11106
11709
|
this.#strings = mergeUiStrings({ ...this.#readStringOverrides(), ...this.strings });
|
|
11107
11710
|
if (this.getAttribute("data-theme-toggle") !== null) {
|
|
11108
11711
|
const saved = this.#readScopedItem(THEME_KEY);
|
|
@@ -11123,6 +11726,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11123
11726
|
this.#builtinStore = namespace === "" ? this.conversationStore : new SessionStorageStore(namespace);
|
|
11124
11727
|
this.conversationStore = this.#builtinStore;
|
|
11125
11728
|
}
|
|
11729
|
+
window.addEventListener("resize", this.#onViewportResize);
|
|
11126
11730
|
this.#wireThreadStore();
|
|
11127
11731
|
this.#wireAttachments();
|
|
11128
11732
|
this.#wireVoice();
|
|
@@ -11185,6 +11789,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11185
11789
|
*/
|
|
11186
11790
|
disconnectedCallback() {
|
|
11187
11791
|
this.#connected = false;
|
|
11792
|
+
window.removeEventListener("resize", this.#onViewportResize);
|
|
11188
11793
|
if (this.#claimedNs !== null) {
|
|
11189
11794
|
CLAIMED_NAMESPACES.delete(this.#claimedNs);
|
|
11190
11795
|
this.#claimedNs = null;
|
|
@@ -11257,6 +11862,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11257
11862
|
this.#fileInput.accept = accept;
|
|
11258
11863
|
this.#attachButton.hidden = false;
|
|
11259
11864
|
this.#enableDragAndDrop();
|
|
11865
|
+
this.#enablePaste();
|
|
11260
11866
|
}
|
|
11261
11867
|
/** The built-in multipart upload handler for `data-attachments-url`, or `null`. */
|
|
11262
11868
|
#defaultUploadHandler(url) {
|
|
@@ -11286,7 +11892,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11286
11892
|
}
|
|
11287
11893
|
this.#voice = new VoiceInput({
|
|
11288
11894
|
transcribe,
|
|
11289
|
-
onText: (
|
|
11895
|
+
onText: (text4) => this.#insertVoiceText(text4),
|
|
11290
11896
|
strings: this.#strings
|
|
11291
11897
|
});
|
|
11292
11898
|
this.#voiceSlot.appendChild(this.#voice.element);
|
|
@@ -11303,9 +11909,9 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11303
11909
|
});
|
|
11304
11910
|
}
|
|
11305
11911
|
/** Drop a voice transcript into the composer (appended to any typed text). */
|
|
11306
|
-
#insertVoiceText(
|
|
11912
|
+
#insertVoiceText(text4) {
|
|
11307
11913
|
const current = this.#input.value.trim();
|
|
11308
|
-
this.#input.value = current === "" ?
|
|
11914
|
+
this.#input.value = current === "" ? text4 : `${current} ${text4}`;
|
|
11309
11915
|
this.#onInput();
|
|
11310
11916
|
this.#input.focus();
|
|
11311
11917
|
}
|
|
@@ -11323,8 +11929,8 @@ var AgUiChat = class extends HTMLElement {
|
|
|
11323
11929
|
*
|
|
11324
11930
|
* No-ops on text that is empty or only whitespace.
|
|
11325
11931
|
*/
|
|
11326
|
-
quote(
|
|
11327
|
-
const quoted = asQuote(
|
|
11932
|
+
quote(text4) {
|
|
11933
|
+
const quoted = asQuote(text4);
|
|
11328
11934
|
if (quoted === "") {
|
|
11329
11935
|
return;
|
|
11330
11936
|
}
|
|
@@ -11363,7 +11969,7 @@ ${quoted}`;
|
|
|
11363
11969
|
within,
|
|
11364
11970
|
label: this.#strings.quoteSelection,
|
|
11365
11971
|
exclude: this,
|
|
11366
|
-
onQuote: (
|
|
11972
|
+
onQuote: (text4) => this.quote(text4)
|
|
11367
11973
|
});
|
|
11368
11974
|
this.#pageQuote = offer;
|
|
11369
11975
|
return () => {
|
|
@@ -11491,6 +12097,37 @@ ${quoted}`;
|
|
|
11491
12097
|
}
|
|
11492
12098
|
});
|
|
11493
12099
|
}
|
|
12100
|
+
/**
|
|
12101
|
+
* Accept files pasted into the composer.
|
|
12102
|
+
*
|
|
12103
|
+
* The whole tray already exists behind this: a paste is one more way to hand
|
|
12104
|
+
* it a `File`, alongside the picker and a drop.
|
|
12105
|
+
*
|
|
12106
|
+
* Two rules keep it from stealing a paste that was never about files.
|
|
12107
|
+
* `clipboardData.files` is empty for text, so ordinary pasting is untouched.
|
|
12108
|
+
* And the default is only prevented when the clipboard carries **no text**:
|
|
12109
|
+
* copying a rich selection that happens to contain an image puts both on the
|
|
12110
|
+
* clipboard, and swallowing the words someone meant to paste in order to
|
|
12111
|
+
* attach a picture they did not is the worse of the two failures.
|
|
12112
|
+
*/
|
|
12113
|
+
#enablePaste() {
|
|
12114
|
+
this.#chat.addEventListener("paste", (event) => {
|
|
12115
|
+
const clipboard = event.clipboardData ?? null;
|
|
12116
|
+
if (clipboard === null) {
|
|
12117
|
+
return;
|
|
12118
|
+
}
|
|
12119
|
+
const files = Array.from(clipboard.files);
|
|
12120
|
+
if (files.length === 0) {
|
|
12121
|
+
return;
|
|
12122
|
+
}
|
|
12123
|
+
if (clipboard.getData("text/plain") === "") {
|
|
12124
|
+
event.preventDefault();
|
|
12125
|
+
}
|
|
12126
|
+
for (const file of files) {
|
|
12127
|
+
this.#attachTray?.add(named(file));
|
|
12128
|
+
}
|
|
12129
|
+
});
|
|
12130
|
+
}
|
|
11494
12131
|
/**
|
|
11495
12132
|
* When `data-threads-url` is set, route thread enumeration / load / rename /
|
|
11496
12133
|
* delete through that server endpoint (wrapping the current store as the
|
|
@@ -11598,18 +12235,18 @@ ${quoted}`;
|
|
|
11598
12235
|
void this.sendMessage(`/${skill.name}`);
|
|
11599
12236
|
return;
|
|
11600
12237
|
}
|
|
11601
|
-
const { text:
|
|
12238
|
+
const { text: text4, missing } = fillTemplate(skill.prompt, this.skillContext());
|
|
11602
12239
|
if (missing.length > 0) {
|
|
11603
12240
|
this.#skillHint.textContent = this.#strings.skillNeeds.replace("{title}", skill.title).replace("{fields}", missing.join(", "));
|
|
11604
12241
|
this.#skillHint.hidden = false;
|
|
11605
|
-
this.#input.value =
|
|
12242
|
+
this.#input.value = text4;
|
|
11606
12243
|
this.#autoGrow();
|
|
11607
12244
|
this.#input.focus();
|
|
11608
|
-
this.#selectFirstPlaceholder(
|
|
12245
|
+
this.#selectFirstPlaceholder(text4);
|
|
11609
12246
|
return;
|
|
11610
12247
|
}
|
|
11611
12248
|
this.#skillHint.hidden = true;
|
|
11612
|
-
this.#input.value =
|
|
12249
|
+
this.#input.value = text4;
|
|
11613
12250
|
this.#autoGrow();
|
|
11614
12251
|
if (skill.sendImmediately === false) {
|
|
11615
12252
|
this.#input.focus();
|
|
@@ -11623,9 +12260,9 @@ ${quoted}`;
|
|
|
11623
12260
|
* Typing then replaces it, which is the shortest path from "this skill needs
|
|
11624
12261
|
* a topic" to a sendable prompt.
|
|
11625
12262
|
*/
|
|
11626
|
-
#selectFirstPlaceholder(
|
|
11627
|
-
const start =
|
|
11628
|
-
this.#input.setSelectionRange(start,
|
|
12263
|
+
#selectFirstPlaceholder(text4) {
|
|
12264
|
+
const start = text4.indexOf("{");
|
|
12265
|
+
this.#input.setSelectionRange(start, text4.indexOf("}", start) + 1);
|
|
11629
12266
|
}
|
|
11630
12267
|
/** Whether the widget is collapsed (reflected as the `collapsed` attribute). */
|
|
11631
12268
|
get collapsed() {
|
|
@@ -11642,6 +12279,9 @@ ${quoted}`;
|
|
|
11642
12279
|
* its own chrome.
|
|
11643
12280
|
*/
|
|
11644
12281
|
setCollapsed(collapsed) {
|
|
12282
|
+
if (!collapsed) {
|
|
12283
|
+
this.#restoreLauncherPosition();
|
|
12284
|
+
}
|
|
11645
12285
|
if (collapsed) {
|
|
11646
12286
|
this.setAttribute("collapsed", "");
|
|
11647
12287
|
} else {
|
|
@@ -11714,13 +12354,32 @@ ${quoted}`;
|
|
|
11714
12354
|
const before = this.getBoundingClientRect();
|
|
11715
12355
|
const width = this.style.getPropertyValue("--ag-ui-width");
|
|
11716
12356
|
const height = this.style.getPropertyValue("--ag-ui-height");
|
|
11717
|
-
this.#
|
|
11718
|
-
const
|
|
12357
|
+
const shrunk = this.#probeAnchor(before, -1);
|
|
12358
|
+
const grown = shrunk.x === null || shrunk.y === null ? this.#probeAnchor(before, 1) : shrunk;
|
|
11719
12359
|
this.#restoreProperty("--ag-ui-width", width);
|
|
11720
12360
|
this.#restoreProperty("--ag-ui-height", height);
|
|
11721
12361
|
return {
|
|
11722
|
-
|
|
11723
|
-
|
|
12362
|
+
// Neither direction moved it: the axis cannot be resized at all, so the
|
|
12363
|
+
// floating default is the best answer available and is the one the
|
|
12364
|
+
// stylesheet would have used with no measurement at all.
|
|
12365
|
+
x: shrunk.x ?? grown.x ?? "right",
|
|
12366
|
+
y: shrunk.y ?? grown.y ?? "bottom"
|
|
12367
|
+
};
|
|
12368
|
+
}
|
|
12369
|
+
/**
|
|
12370
|
+
* Which edge each axis holds still when the panel changes size by `delta`.
|
|
12371
|
+
*
|
|
12372
|
+
* Null for an axis whose size did not change: nothing moved, so nothing was
|
|
12373
|
+
* learned, and reporting the unmoved edge as the pinned one would be exactly
|
|
12374
|
+
* backwards.
|
|
12375
|
+
*/
|
|
12376
|
+
#probeAnchor(before, delta) {
|
|
12377
|
+
this.#applySize({ width: before.width + delta, height: before.height + delta });
|
|
12378
|
+
const after = this.getBoundingClientRect();
|
|
12379
|
+
const moved = (a, b2) => Math.abs(a - b2) >= 0.5;
|
|
12380
|
+
return {
|
|
12381
|
+
x: moved(after.width, before.width) ? moved(after.left, before.left) ? "right" : "left" : null,
|
|
12382
|
+
y: moved(after.height, before.height) ? moved(after.top, before.top) ? "bottom" : "top" : null
|
|
11724
12383
|
};
|
|
11725
12384
|
}
|
|
11726
12385
|
/** Stamp the measured anchor so the shadow CSS can place the grip. */
|
|
@@ -11728,8 +12387,10 @@ ${quoted}`;
|
|
|
11728
12387
|
if (!this.#connected) {
|
|
11729
12388
|
return;
|
|
11730
12389
|
}
|
|
11731
|
-
const anchor = this.#measureAnchor();
|
|
12390
|
+
const anchor = this.#expandCorner ?? this.#measureAnchor();
|
|
12391
|
+
this.#anchor = anchor;
|
|
11732
12392
|
this.setAttribute("data-resize-anchor", `${anchor.y}-${anchor.x}`);
|
|
12393
|
+
this.#focusableGrip();
|
|
11733
12394
|
}
|
|
11734
12395
|
/** Put a custom property back to a previous value, or remove it if there was none. */
|
|
11735
12396
|
#restoreProperty(name, value) {
|
|
@@ -11778,6 +12439,203 @@ ${quoted}`;
|
|
|
11778
12439
|
this.style.removeProperty("--ag-ui-width");
|
|
11779
12440
|
}
|
|
11780
12441
|
}
|
|
12442
|
+
/**
|
|
12443
|
+
* Whether this placement lets the launcher be dragged, read per interaction
|
|
12444
|
+
* because `placement` is a live attribute. `data-launcher-drag="false"` opts
|
|
12445
|
+
* a host out without giving up the launcher itself.
|
|
12446
|
+
*/
|
|
12447
|
+
#launcherDraggable() {
|
|
12448
|
+
return this.getAttribute("data-launcher-drag") !== "false" && DRAGGABLE_PLACEMENTS.has(this.getAttribute("placement"));
|
|
12449
|
+
}
|
|
12450
|
+
/** The viewport the launcher and the panel both have to fit inside. */
|
|
12451
|
+
#viewport() {
|
|
12452
|
+
return { width: window.innerWidth, height: window.innerHeight };
|
|
12453
|
+
}
|
|
12454
|
+
/**
|
|
12455
|
+
* The launcher's box in viewport coordinates, with its transform divided out.
|
|
12456
|
+
*
|
|
12457
|
+
* The launcher is scaled in four states -- the collapse animation, hover,
|
|
12458
|
+
* press, and the resting scale(0.4) it sits at while the panel is open -- and
|
|
12459
|
+
* `getBoundingClientRect` reports every one of them. A drag that started from
|
|
12460
|
+
* that rect would begin a couple of pixels off, because a press is one of
|
|
12461
|
+
* those states.
|
|
12462
|
+
*
|
|
12463
|
+
* So the size comes from `offsetWidth`/`offsetHeight`, which are layout
|
|
12464
|
+
* metrics no transform reaches, and the position from the rect's *centre*,
|
|
12465
|
+
* which a centred scale is the one point that cannot move.
|
|
12466
|
+
*/
|
|
12467
|
+
#launcherBox() {
|
|
12468
|
+
const width = this.#launcher.offsetWidth;
|
|
12469
|
+
const height = this.#launcher.offsetHeight;
|
|
12470
|
+
const dragged = this.#launcherPos;
|
|
12471
|
+
if (dragged !== null) {
|
|
12472
|
+
return { left: dragged.left, top: dragged.top, width, height };
|
|
12473
|
+
}
|
|
12474
|
+
const rect = this.#launcher.getBoundingClientRect();
|
|
12475
|
+
return {
|
|
12476
|
+
left: rect.left + rect.width / 2 - width / 2,
|
|
12477
|
+
top: rect.top + rect.height / 2 - height / 2,
|
|
12478
|
+
width,
|
|
12479
|
+
height
|
|
12480
|
+
};
|
|
12481
|
+
}
|
|
12482
|
+
/**
|
|
12483
|
+
* Place the host box and the launcher for the position the user dragged to.
|
|
12484
|
+
*
|
|
12485
|
+
* This writes `--ag-ui-inset`, which is a host-facing property: an inline
|
|
12486
|
+
* value outranks the page's own rule for it, exactly as a dragged width
|
|
12487
|
+
* outranks a placement's. That is the intent -- the user moved it -- and it
|
|
12488
|
+
* is why switching to a placement that owns its position hands the property
|
|
12489
|
+
* back rather than leaving a stale inline one behind.
|
|
12490
|
+
*/
|
|
12491
|
+
#applyLauncherPlacement(at2) {
|
|
12492
|
+
if (!this.#launcherDraggable()) {
|
|
12493
|
+
return;
|
|
12494
|
+
}
|
|
12495
|
+
this.#launcherPos = at2;
|
|
12496
|
+
const panel = this.getBoundingClientRect();
|
|
12497
|
+
const placement = launcherPlacement(
|
|
12498
|
+
this.#launcherBox(),
|
|
12499
|
+
{ width: panel.width, height: panel.height },
|
|
12500
|
+
this.#viewport()
|
|
12501
|
+
);
|
|
12502
|
+
this.style.setProperty("--ag-ui-inset", placement.hostInset);
|
|
12503
|
+
this.style.setProperty("--ag-ui-launcher-inset", placement.launcherInset);
|
|
12504
|
+
this.#expandCorner = placement.corner;
|
|
12505
|
+
this.setAttribute("data-expand-corner", `${placement.corner.y}-${placement.corner.x}`);
|
|
12506
|
+
this.#syncResizeAnchor();
|
|
12507
|
+
}
|
|
12508
|
+
/** Move the launcher live during a drag, without persisting. */
|
|
12509
|
+
#moveLauncher(left, top) {
|
|
12510
|
+
this.#applyLauncherPlacement({ left, top });
|
|
12511
|
+
}
|
|
12512
|
+
/** Move the launcher and remember where, per tab, like the dragged size. */
|
|
12513
|
+
#commitLauncher(left, top) {
|
|
12514
|
+
this.#moveLauncher(left, top);
|
|
12515
|
+
this.#storeLauncherPosition();
|
|
12516
|
+
}
|
|
12517
|
+
/** Write the current launcher position, if this element owns one. */
|
|
12518
|
+
#storeLauncherPosition() {
|
|
12519
|
+
const position = this.#launcherPos;
|
|
12520
|
+
if (position === null) {
|
|
12521
|
+
return;
|
|
12522
|
+
}
|
|
12523
|
+
writeStoredItem(this.#storageKey(LAUNCHER_KEY), JSON.stringify(position));
|
|
12524
|
+
}
|
|
12525
|
+
/**
|
|
12526
|
+
* Re-apply the dragged position against the current viewport: on connect,
|
|
12527
|
+
* whenever the window resizes, and before an expand. The viewport that
|
|
12528
|
+
* stored a position may since have shrunk, and a launcher past the edge is
|
|
12529
|
+
* unreachable -- it is the only way back to a collapsed conversation.
|
|
12530
|
+
*/
|
|
12531
|
+
#restoreLauncherPosition() {
|
|
12532
|
+
const stored = this.#launcherPos ?? this.#readLauncherPosition();
|
|
12533
|
+
if (stored === null) {
|
|
12534
|
+
return;
|
|
12535
|
+
}
|
|
12536
|
+
const box = this.#launcherBox();
|
|
12537
|
+
this.#applyLauncherPlacement(
|
|
12538
|
+
clampLauncher({ ...box, left: stored.left, top: stored.top }, this.#viewport())
|
|
12539
|
+
);
|
|
12540
|
+
}
|
|
12541
|
+
/** The persisted launcher position for this instance, or null. */
|
|
12542
|
+
#readLauncherPosition() {
|
|
12543
|
+
const raw = this.#readScopedItem(LAUNCHER_KEY);
|
|
12544
|
+
if (raw === null) {
|
|
12545
|
+
return null;
|
|
12546
|
+
}
|
|
12547
|
+
try {
|
|
12548
|
+
const parsed = JSON.parse(raw);
|
|
12549
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
12550
|
+
return null;
|
|
12551
|
+
}
|
|
12552
|
+
const { left, top } = parsed;
|
|
12553
|
+
return typeof left === "number" && typeof top === "number" ? { left, top } : null;
|
|
12554
|
+
} catch {
|
|
12555
|
+
return null;
|
|
12556
|
+
}
|
|
12557
|
+
}
|
|
12558
|
+
/**
|
|
12559
|
+
* Give the position back to the host when the new placement owns it, the way
|
|
12560
|
+
* #releaseOwnedAxes gives back a size. Without this a dragged inset survives
|
|
12561
|
+
* the switch inline and pins a sidebar to wherever the floating launcher was.
|
|
12562
|
+
*/
|
|
12563
|
+
#releaseLauncherPosition() {
|
|
12564
|
+
if (this.#launcherDraggable()) {
|
|
12565
|
+
return;
|
|
12566
|
+
}
|
|
12567
|
+
this.#launcherPos = null;
|
|
12568
|
+
this.#expandCorner = null;
|
|
12569
|
+
this.style.removeProperty("--ag-ui-inset");
|
|
12570
|
+
this.style.removeProperty("--ag-ui-launcher-inset");
|
|
12571
|
+
this.removeAttribute("data-expand-corner");
|
|
12572
|
+
}
|
|
12573
|
+
/**
|
|
12574
|
+
* Apply the box a grip is asking for.
|
|
12575
|
+
*
|
|
12576
|
+
* The size is the easy half. The other half is that **dragging the edge the
|
|
12577
|
+
* layout is holding still moves the panel as well as resizing it**, and the
|
|
12578
|
+
* layout cannot express that on its own: a floating panel pinned bottom-right
|
|
12579
|
+
* cannot grow rightward, because its right edge is what the placement fixed.
|
|
12580
|
+
* So a grip on a pinned edge takes the position over -- which is the same
|
|
12581
|
+
* ownership the launcher drag takes, written the same way.
|
|
12582
|
+
*
|
|
12583
|
+
* A grip on a free edge writes nothing but the size, exactly as before, so a
|
|
12584
|
+
* host positioning the panel with its own rule keeps that rule until someone
|
|
12585
|
+
* drags the edge it was holding.
|
|
12586
|
+
*/
|
|
12587
|
+
#applyResize(grip, box) {
|
|
12588
|
+
this.#applySize({ width: box.right - box.left, height: box.bottom - box.top });
|
|
12589
|
+
if (grip.x !== this.#anchor.x && grip.y !== this.#anchor.y) {
|
|
12590
|
+
return;
|
|
12591
|
+
}
|
|
12592
|
+
const viewport = this.#viewport();
|
|
12593
|
+
const anchor = this.#anchor;
|
|
12594
|
+
const side = (value) => `${Math.round(value)}px`;
|
|
12595
|
+
this.style.setProperty(
|
|
12596
|
+
"--ag-ui-inset",
|
|
12597
|
+
[
|
|
12598
|
+
anchor.y === "top" ? side(box.top) : "auto",
|
|
12599
|
+
anchor.x === "right" ? side(viewport.width - box.right) : "auto",
|
|
12600
|
+
anchor.y === "bottom" ? side(viewport.height - box.bottom) : "auto",
|
|
12601
|
+
anchor.x === "left" ? side(box.left) : "auto"
|
|
12602
|
+
].join(" ")
|
|
12603
|
+
);
|
|
12604
|
+
if (this.#launcherPos !== null) {
|
|
12605
|
+
const size = this.#launcher.offsetWidth;
|
|
12606
|
+
this.#launcherPos = {
|
|
12607
|
+
left: anchor.x === "left" ? box.left : box.right - size,
|
|
12608
|
+
top: anchor.y === "top" ? box.top : box.bottom - size
|
|
12609
|
+
};
|
|
12610
|
+
}
|
|
12611
|
+
}
|
|
12612
|
+
/** Finish a resize: keep the box, remember it, and re-read the pinned edges. */
|
|
12613
|
+
#commitResize(grip, box) {
|
|
12614
|
+
this.#applyResize(grip, box);
|
|
12615
|
+
this.#persistSize({ width: box.right - box.left, height: box.bottom - box.top });
|
|
12616
|
+
this.#storeLauncherPosition();
|
|
12617
|
+
this.#syncResizeAnchor();
|
|
12618
|
+
}
|
|
12619
|
+
/**
|
|
12620
|
+
* Put the tab stop on the grip diagonally opposite the pinned corner.
|
|
12621
|
+
*
|
|
12622
|
+
* That is the corner a resize grows the panel from, so an arrow key there
|
|
12623
|
+
* changes the size and never the position -- the behaviour the single grip
|
|
12624
|
+
* this replaced had, kept for the one path that cannot simply grab a
|
|
12625
|
+
* different edge.
|
|
12626
|
+
*/
|
|
12627
|
+
#focusableGrip() {
|
|
12628
|
+
const free = `${this.#anchor.y === "top" ? "bottom" : "top"}-${this.#anchor.x === "left" ? "right" : "left"}`;
|
|
12629
|
+
for (const [name, handle] of this.#resizeHandles) {
|
|
12630
|
+
const reachable = name === free;
|
|
12631
|
+
handle.tabIndex = reachable ? 0 : -1;
|
|
12632
|
+
if (reachable) {
|
|
12633
|
+
handle.removeAttribute("aria-hidden");
|
|
12634
|
+
} else {
|
|
12635
|
+
handle.setAttribute("aria-hidden", "true");
|
|
12636
|
+
}
|
|
12637
|
+
}
|
|
12638
|
+
}
|
|
11781
12639
|
/** Persist a dragged size per tab, alongside the collapsed/theme preferences. */
|
|
11782
12640
|
#persistSize(size) {
|
|
11783
12641
|
const stored = { ...this.#readSize(), ...size };
|
|
@@ -12146,11 +13004,11 @@ ${quoted}`;
|
|
|
12146
13004
|
* the full transcript — tool calls and their results — not just the prose.
|
|
12147
13005
|
*/
|
|
12148
13006
|
#renderHistoricMessage(message) {
|
|
12149
|
-
const
|
|
13007
|
+
const text4 = typeof message.content === "string" ? message.content : "";
|
|
12150
13008
|
if (message.role === MESSAGE_ROLE.USER) {
|
|
12151
13009
|
const attachments = messageAttachments(message);
|
|
12152
|
-
if (
|
|
12153
|
-
const bubble = this.appendMessage(MESSAGE_ROLE.USER,
|
|
13010
|
+
if (text4 !== "" || attachments.length > 0) {
|
|
13011
|
+
const bubble = this.appendMessage(MESSAGE_ROLE.USER, text4);
|
|
12154
13012
|
if (attachments.length > 0) {
|
|
12155
13013
|
bubble.appendChild(renderAttachmentChips(attachments));
|
|
12156
13014
|
}
|
|
@@ -12158,8 +13016,8 @@ ${quoted}`;
|
|
|
12158
13016
|
return;
|
|
12159
13017
|
}
|
|
12160
13018
|
if (message.role === MESSAGE_ROLE.ASSISTANT) {
|
|
12161
|
-
if (
|
|
12162
|
-
const restoredBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT,
|
|
13019
|
+
if (text4 !== "") {
|
|
13020
|
+
const restoredBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT, text4);
|
|
12163
13021
|
restoredBubble.classList.add("message--restored");
|
|
12164
13022
|
this.#attachActions(restoredBubble);
|
|
12165
13023
|
}
|
|
@@ -12453,19 +13311,27 @@ ${quoted}`;
|
|
|
12453
13311
|
this.#badge
|
|
12454
13312
|
);
|
|
12455
13313
|
this.#launcher.addEventListener("click", () => this.setCollapsed(false));
|
|
12456
|
-
this.#
|
|
12457
|
-
|
|
13314
|
+
enableLauncherDrag(this.#launcher, {
|
|
13315
|
+
enabled: () => this.collapsed && this.#launcherDraggable(),
|
|
13316
|
+
rect: () => this.#launcherBox(),
|
|
13317
|
+
viewport: () => this.#viewport(),
|
|
13318
|
+
apply: (left, top) => this.#moveLauncher(left, top),
|
|
13319
|
+
commit: (left, top) => this.#commitLauncher(left, top)
|
|
13320
|
+
});
|
|
13321
|
+
for (const grip of RESIZE_GRIPS) {
|
|
13322
|
+
const handle = createResizeHandle(grip, {
|
|
12458
13323
|
axis: () => this.#resizeAxis(),
|
|
12459
|
-
anchor: () => this.#measureAnchor(),
|
|
12460
13324
|
rect: () => this.getBoundingClientRect(),
|
|
12461
|
-
apply: (
|
|
12462
|
-
commit: (
|
|
12463
|
-
this.#persistSize(size);
|
|
12464
|
-
this.#syncResizeAnchor();
|
|
12465
|
-
},
|
|
13325
|
+
apply: (box) => this.#applyResize(grip, box),
|
|
13326
|
+
commit: (box) => this.#commitResize(grip, box),
|
|
12466
13327
|
label: this.#strings.resizePanel
|
|
12467
|
-
})
|
|
12468
|
-
|
|
13328
|
+
});
|
|
13329
|
+
handle.tabIndex = -1;
|
|
13330
|
+
handle.setAttribute("aria-hidden", "true");
|
|
13331
|
+
this.#resizeHandles.set(gripName(grip), handle);
|
|
13332
|
+
this.#chat.appendChild(handle);
|
|
13333
|
+
}
|
|
13334
|
+
this.#focusableGrip();
|
|
12469
13335
|
this.#adoptStyles();
|
|
12470
13336
|
this.#root.append(this.#announcer, this.#chat, this.#launcher);
|
|
12471
13337
|
}
|
|
@@ -12859,13 +13725,18 @@ ${quoted}`;
|
|
|
12859
13725
|
strings: this.#strings,
|
|
12860
13726
|
// Read at click time, not captured: a bubble rendered from markdown
|
|
12861
13727
|
// holds its text in the DOM, and that is what the user sees and means
|
|
12862
|
-
// to copy.
|
|
12863
|
-
|
|
13728
|
+
// to copy. Serialised rather than read off `textContent`, which welds
|
|
13729
|
+
// a table into one run of digits and picks up the code blocks' own
|
|
13730
|
+
// copy buttons on the way past.
|
|
13731
|
+
...copyable ? {
|
|
13732
|
+
text: () => copyPayload(bubble).text,
|
|
13733
|
+
html: () => copyPayload(bubble).html
|
|
13734
|
+
} : {},
|
|
12864
13735
|
...rateable ? {
|
|
12865
13736
|
onFeedback: (rating) => {
|
|
12866
13737
|
this.dispatchEvent(
|
|
12867
13738
|
new CustomEvent(FEEDBACK_EVENT, {
|
|
12868
|
-
detail: { content: bubble.
|
|
13739
|
+
detail: { content: copyPayload(bubble).text, rating },
|
|
12869
13740
|
bubbles: true,
|
|
12870
13741
|
composed: true
|
|
12871
13742
|
})
|
|
@@ -12881,7 +13752,7 @@ ${quoted}`;
|
|
|
12881
13752
|
/** Move the Retry button onto `bar`, taking it off whoever held it. */
|
|
12882
13753
|
#moveRetryTo(bar) {
|
|
12883
13754
|
this.#retryOwner?.querySelector(".message-action--retry")?.remove();
|
|
12884
|
-
const retry = messageActionButton("retry", this.#strings.retryMessage,
|
|
13755
|
+
const retry = messageActionButton("retry", this.#strings.retryMessage, ICON_RETRY);
|
|
12885
13756
|
retry.addEventListener("click", () => {
|
|
12886
13757
|
void this.retryLastTurn();
|
|
12887
13758
|
});
|
|
@@ -13144,7 +14015,11 @@ ${quoted}`;
|
|
|
13144
14015
|
this.#closeSubAgent(subagentRunId, SUBAGENT_PHASE.FINISHED, null);
|
|
13145
14016
|
},
|
|
13146
14017
|
onSubAgentError: (subagentRunId, message) => {
|
|
13147
|
-
this.#closeSubAgent(
|
|
14018
|
+
this.#closeSubAgent(
|
|
14019
|
+
subagentRunId,
|
|
14020
|
+
SUBAGENT_PHASE.FAILED,
|
|
14021
|
+
message === "" ? this.#strings.subAgentFailed : message
|
|
14022
|
+
);
|
|
13148
14023
|
},
|
|
13149
14024
|
onMessagesSnapshot: () => {
|
|
13150
14025
|
this.#appendNotice("\u{1F504}", this.#strings.historyReplaced, "history-replaced");
|
|
@@ -13491,8 +14366,8 @@ ${quoted}`;
|
|
|
13491
14366
|
this.#appendNotice("\u2728", this.#strings.usingSkill.replace("{name}", skill), "skill");
|
|
13492
14367
|
return true;
|
|
13493
14368
|
}
|
|
13494
|
-
#appendNotice(icon,
|
|
13495
|
-
this.#ensureGroup().appendChild(renderRunNotice(icon,
|
|
14369
|
+
#appendNotice(icon, text4, kind) {
|
|
14370
|
+
this.#ensureGroup().appendChild(renderRunNotice(icon, text4, kind));
|
|
13496
14371
|
this.#updateEmptyState();
|
|
13497
14372
|
this.#scroller.follow();
|
|
13498
14373
|
}
|
|
@@ -13699,6 +14574,16 @@ function confirmPhrase(interrupt) {
|
|
|
13699
14574
|
function restoredToolCalls(value) {
|
|
13700
14575
|
return Array.isArray(value) ? value.filter(isRestoredToolCall) : [];
|
|
13701
14576
|
}
|
|
14577
|
+
function named(file) {
|
|
14578
|
+
if (file.name !== "") {
|
|
14579
|
+
return file;
|
|
14580
|
+
}
|
|
14581
|
+
const subtype = file.type.split("/")[1] ?? file.type;
|
|
14582
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
14583
|
+
return new File([file], subtype === "" ? `pasted-${stamp}` : `pasted-${stamp}.${subtype}`, {
|
|
14584
|
+
type: file.type
|
|
14585
|
+
});
|
|
14586
|
+
}
|
|
13702
14587
|
function isRestoredToolCall(value) {
|
|
13703
14588
|
if (typeof value !== "object" || value === null) {
|
|
13704
14589
|
return false;
|
|
@@ -13758,7 +14643,7 @@ function setControlValue(el2, value) {
|
|
|
13758
14643
|
}
|
|
13759
14644
|
|
|
13760
14645
|
// src/version.ts
|
|
13761
|
-
var VERSION = "0.
|
|
14646
|
+
var VERSION = "0.33.1";
|
|
13762
14647
|
export {
|
|
13763
14648
|
ATTACHMENT_EVENT,
|
|
13764
14649
|
AgUiChat,
|
|
@@ -13850,6 +14735,6 @@ export {
|
|
|
13850
14735
|
/*! Bundled license information:
|
|
13851
14736
|
|
|
13852
14737
|
dompurify/dist/purify.es.mjs:
|
|
13853
|
-
(*! @license DOMPurify 3.4.
|
|
14738
|
+
(*! @license DOMPurify 3.4.14 | (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.14/LICENSE *)
|
|
13854
14739
|
*/
|
|
13855
14740
|
//# sourceMappingURL=index.js.map
|