PageSourceSearch

https://hunter.io/assets/purify.es-DuxowUZt.js

js hunter.io collected 2026-09-24 07:50:18 UTC 83,824 bytes, 2,381 lines download raw bytes

vendor: 7,252 bytes, lines 1-193
1(function() {
2	try {
3		var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
4		e.SENTRY_RELEASE = { id: "b96dc26" };
5		var n = new e.Error().stack;
6		n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "210a779f-938b-4d2e-a2f7-65aeca084e9e", e._sentryDebugIdIdentifier = "sentry-dbid-210a779f-938b-4d2e-a2f7-65aeca084e9e");
7	} catch (e) {}
8})();
9import { n as __esmMin } from "./rolldown-runtime-sLwMD6dS.js";
10//#region node_modules/.pnpm/[email protected]/node_modules/dompurify/dist/purify.es.mjs
11/*! @license DOMPurify 3.4.15 | (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.15/LICENSE */
12function _arrayLikeToArray(r, a) {
13	(null == a || a > r.length) && (a = r.length);
14	for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
15	return n;
16}
17function _arrayWithHoles(r) {
18	if (Array.isArray(r)) return r;
19}
20function _iterableToArrayLimit(r, l) {
21	var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
22	if (null != t) {
23		var e, n, i, u, a = [], f = true, o = false;
24		try {
25			if (i = (t = t.call(r)).next, 0 === l);
26			else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
27		} catch (r) {
28			o = true, n = r;
29		} finally {
30			try {
31				if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
32			} finally {
33				if (o) throw n;
34			}
35		}
36		return a;
37	}
38}
39function _nonIterableRest() {
40	throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
41}
42function _slicedToArray(r, e) {
43	return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
44}
45function _unsupportedIterableToArray(r, a) {
46	if (r) {
47		if ("string" == typeof r) return _arrayLikeToArray(r, a);
48		var t = {}.toString.call(r).slice(8, -1);
49		return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
50	}
51}
52/**
53* Creates a new function that calls the given function with a specified thisArg and arguments.
54*
55* @param func - The function to be wrapped and called.
56* @returns A new function that calls the given function with a specified thisArg and arguments.
57*/
58function unapply(func) {
59	return function(thisArg) {
60		if (thisArg instanceof RegExp) thisArg.lastIndex = 0;
61		for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) args[_key3 - 1] = arguments[_key3];
62		return apply(func, thisArg, args);
63	};
64}
65/**
66* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
67*
68* @param func - The constructor function to be wrapped and called.
69* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
70*/
71function unconstruct(Func) {
72	return function() {
73		for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) args[_key4] = arguments[_key4];
74		return construct(Func, args);
75	};
76}
77/**
78* Add properties to a lookup table
79*
80* @param set - The set to which elements will be added.
81* @param array - The array containing elements to be added to the set.
82* @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
83* @returns The modified set with added elements.
84*/
85function addToSet(set, array) {
86	let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
87	if (setPrototypeOf) setPrototypeOf(set, null);
88	if (!arrayIsArray(array)) return set;
89	let l = array.length;
90	while (l--) {
91		let element = array[l];
92		if (typeof element === "string") {
93			const lcElement = transformCaseFunc(element);
94			if (lcElement !== element) {
95				if (!isFrozen(array)) array[l] = lcElement;
96				element = lcElement;
97			}
98		}
99		set[element] = true;
100	}
101	return set;
102}
103/**
104* Clean up an array to harden against CSPP
105*
106* @param array - The array to be cleaned.
107* @returns The cleaned version of the array
108*/
109function cleanArray(array) {
110	for (let index = 0; index < array.length; index++) if (!objectHasOwnProperty(array, index)) array[index] = null;
111	return array;
112}
113/**
114* Shallow clone an object
115*
116* @param object - The object to be cloned.
117* @returns A new object that copies the original.
118*/
119function clone(object) {
120	const newObject = create(null);
121	for (const _ref2 of entries(object)) {
122		var _ref3 = _slicedToArray(_ref2, 2);
123		const property = _ref3[0];
124		const value = _ref3[1];
125		if (objectHasOwnProperty(object, property)) {
126			if (arrayIsArray(value)) newObject[property] = cleanArray(value);
127			else if (value && typeof value === "object" && value.constructor === Object) newObject[property] = clone(value);
128			else newObject[property] = value;
129		}
130	}
131	return newObject;
132}
133/**
134* Convert non-node values into strings without depending on direct property access.
135*
136* @param value - The value to stringify.
137* @returns A string representation of the provided value.
138*/
139function stringifyValue(value) {
140	switch (typeof value) {
141		case "string": return value;
142		case "number": return numberToString(value);
143		case "boolean": return booleanToString(value);
144		case "bigint": return bigintToString ? bigintToString(value) : "0";
145		case "symbol": return symbolToString ? symbolToString(value) : "Symbol()";
146		case "undefined": return objectToString(value);
147		case "function":
148		case "object": {
149			if (value === null) return objectToString(value);
150			const valueAsRecord = value;
151			const valueToString = lookupGetter(valueAsRecord, "toString");
152			if (typeof valueToString === "function") {
153				const stringified = valueToString(valueAsRecord);
154				return typeof stringified === "string" ? stringified : objectToString(stringified);
155			}
156			return objectToString(value);
157		}
158		default: return objectToString(value);
159	}
160}
161/**
162* This method automatically checks if the prop is function or getter and behaves accordingly.
163*
164* @param object - The object to look up the getter function in its prototype chain.
165* @param prop - The property name for which to find the getter function.
166* @returns The getter function found in the prototype chain or a fallback function.
167*/
168function lookupGetter(object, prop) {
169	while (object !== null) {
170		const desc = getOwnPropertyDescriptor(object, prop);
171		if (desc) {
172			if (desc.get) return unapply(desc.get);
173			if (typeof desc.value === "function") return unapply(desc.value);
174		}
175		object = getPrototypeOf(object);
176	}
177	function fallbackValue() {
178		return null;
179	}
180	return fallbackValue;
181}
182function isRegex(value) {
183	try {
184		regExpTest(value, "");
185		return true;
186	} catch (_unused) {
187		return false;
188	}
189}
190function createDOMPurify() {
191	let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
192	const DOMPurify = (root) => createDOMPurify(root);
193	DOMPurify.version = "3.4.15
vendor: 44,004 bytes, lines 193-1183
193";
194	DOMPurify.removed = [];
195	if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
196		DOMPurify.isSupported = false;
197		return DOMPurify;
198	}
199	let document = window.document;
200	const originalDocument = document;
201	const currentScript = originalDocument.currentScript;
202	window.DocumentFragment;
203	const HTMLTemplateElement = window.HTMLTemplateElement, Node = window.Node, Element = window.Element, NodeFilter = window.NodeFilter;
204	window.NamedNodeMap === void 0 && (window.NamedNodeMap || window.MozNamedAttrMap);
205	window.HTMLFormElement;
206	const DOMParser = window.DOMParser, trustedTypes = window.trustedTypes;
207	const ElementPrototype = Element.prototype;
208	const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
209	const remove = lookupGetter(ElementPrototype, "remove");
210	const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
211	const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
212	const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
213	const getParentNode = lookupGetter(ElementPrototype, "parentNode");
214	const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
215	const getAttributes = lookupGetter(ElementPrototype, "attributes");
216	const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
217	const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
218	const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, "ownerDocument") : null;
219	const _readNodeType = function _readNodeType(node) {
220		return getNodeType ? getNodeType(node) : node.nodeType;
221	};
222	const _readNodeName = function _readNodeName(node) {
223		return getNodeName ? getNodeName(node) : node.nodeName;
224	};
225	if (typeof HTMLTemplateElement === "function") {
226		const template = document.createElement("template");
227		if (template.content && template.content.ownerDocument) document = template.content.ownerDocument;
228	}
229	let trustedTypesPolicy;
230	let emptyHTML = "";
231	let defaultTrustedTypesPolicy;
232	let defaultTrustedTypesPolicyResolved = false;
233	let IN_TRUSTED_TYPES_POLICY = 0;
234	const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy() {
235		if (IN_TRUSTED_TYPES_POLICY > 0) throw typeErrorCreate("A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the \"DOMPurify and Trusted Types\" section of the README.");
236	};
237	const _createTrustedHTML = function _createTrustedHTML(html) {
238		_assertNotInTrustedTypesPolicy();
239		IN_TRUSTED_TYPES_POLICY++;
240		try {
241			return trustedTypesPolicy.createHTML(html);
242		} finally {
243			IN_TRUSTED_TYPES_POLICY--;
244		}
245	};
246	const _createTrustedScriptURL = function _createTrustedScriptURL(scriptUrl) {
247		_assertNotInTrustedTypesPolicy();
248		IN_TRUSTED_TYPES_POLICY++;
249		try {
250			return trustedTypesPolicy.createScriptURL(scriptUrl);
251		} finally {
252			IN_TRUSTED_TYPES_POLICY--;
253		}
254	};
255	const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy() {
256		if (!defaultTrustedTypesPolicyResolved) {
257			defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
258			defaultTrustedTypesPolicyResolved = true;
259		}
260		return defaultTrustedTypesPolicy;
261	};
262	const _document = document, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
263	const importNode = originalDocument.importNode;
264	let hooks = _createHooksMap();
265	/**
266	* Expose whether this browser supports running the full DOMPurify.
267	*/
268	DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
269	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;
270	let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
271	/**
272	* We consider the elements and attributes below to be safe. Ideally
273	* don't add any new ones but feel free to remove unwanted ones.
274	*/
275	let ALLOWED_TAGS = null;
276	const DEFAULT_ALLOWED_TAGS = addToSet({}, [
277		...html$1,
278		...svg$1,
279		...svgFilters,
280		...mathMl$1,
281		...text
282	]);
283	let ALLOWED_ATTR = null;
284	const DEFAULT_ALLOWED_ATTR = addToSet({}, [
285		...html,
286		...svg,
287		...mathMl,
288		...xml
289	]);
290	let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
291		tagNameCheck: {
292			writable: true,
293			configurable: false,
294			enumerable: true,
295			value: null
296		},
297		attributeNameCheck: {
298			writable: true,
299			configurable: false,
300			enumerable: true,
301			value: null
302		},
303		allowCustomizedBuiltInElements: {
304			writable: true,
305			configurable: false,
306			enumerable: true,
307			value: false
308		}
309	}));
310	let FORBID_TAGS = null;
311	let FORBID_ATTR = null;
312	const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
313		tagCheck: {
314			writable: true,
315			configurable: false,
316			enumerable: true,
317			value: null
318		},
319		attributeCheck: {
320			writable: true,
321			configurable: false,
322			enumerable: true,
323			value: null
324		}
325	}));
326	let ALLOW_ARIA_ATTR = true;
327	let ALLOW_DATA_ATTR = true;
328	let ALLOW_UNKNOWN_PROTOCOLS = false;
329	let ALLOW_SELF_CLOSE_IN_ATTR = true;
330	let SAFE_FOR_TEMPLATES = false;
331	let SAFE_FOR_XML = true;
332	let WHOLE_DOCUMENT = false;
333	let SET_CONFIG = false;
334	let SET_CONFIG_ALLOWED_TAGS = null;
335	let SET_CONFIG_ALLOWED_ATTR = null;
336	let FORCE_BODY = false;
337	let RETURN_DOM = false;
338	let RETURN_DOM_FRAGMENT = false;
339	let RETURN_TRUSTED_TYPE = false;
340	let SANITIZE_DOM = true;
341	let SANITIZE_NAMED_PROPS = false;
342	const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
343	let KEEP_CONTENT = true;
344	let IN_PLACE = false;
345	let USE_PROFILES = {};
346	let FORBID_CONTENTS = null;
347	const DEFAULT_FORBID_CONTENTS = addToSet({}, [
348		"annotation-xml",
349		"audio",
350		"colgroup",
351		"desc",
352		"foreignobject",
353		"head",
354		"iframe",
355		"math",
356		"mi",
357		"mn",
358		"mo",
359		"ms",
360		"mtext",
361		"noembed",
362		"noframes",
363		"noscript",
364		"plaintext",
365		"script",
366		"selectedcontent",
367		"style",
368		"svg",
369		"template",
370		"thead",
371		"title",
372		"video",
373		"xmp"
374	]);
375	let DATA_URI_TAGS = null;
376	const DEFAULT_DATA_URI_TAGS = addToSet({}, [
377		"audio",
378		"video",
379		"img",
380		"source",
381		"image",
382		"track"
383	]);
384	let URI_SAFE_ATTRIBUTES = null;
385	const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [
386		"alt",
387		"class",
388		"for",
389		"id",
390		"label",
391		"name",
392		"pattern",
393		"placeholder",
394		"role",
395		"summary",
396		"title",
397		"value",
398		"style",
399		"xmlns"
400	]);
401	const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
402	const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
403	const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
404	let NAMESPACE = HTML_NAMESPACE;
405	let IS_EMPTY_INPUT = false;
406	let ALLOWED_NAMESPACES = null;
407	const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [
408		MATHML_NAMESPACE,
409		SVG_NAMESPACE,
410		HTML_NAMESPACE
411	], stringToString);
412	const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze([
413		"mi",
414		"mo",
415		"mn",
416		"ms",
417		"mtext"
418	]);
419	let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
420	const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
421	let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
422	const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [
423		"title",
424		"style",
425		"font",
426		"a",
427		"script"
428	]);
429	let PARSER_MEDIA_TYPE = null;
430	const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
431	const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
432	let transformCaseFunc = null;
433	let CONFIG = null;
434	const formElement = document.createElement("form");
435	const isRegexOrFunction = function isRegexOrFunction(testValue) {
436		return testValue instanceof RegExp || testValue instanceof Function;
437	};
438	/**
439	* _parseConfig
440	*
441	* @param cfg optional config literal
442	*/
443	const _parseConfig = function _parseConfig() {
444		let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
445		if (CONFIG && CONFIG === cfg) return;
446		if (!cfg || typeof cfg !== "object") cfg = {};
447		cfg = clone(cfg);
448		PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
449		transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
450		ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, { transform: transformCaseFunc });
451		ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, { transform: transformCaseFunc });
452		ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, { transform: stringToString });
453		URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
454			transform: transformCaseFunc,
455			base: DEFAULT_URI_SAFE_ATTRIBUTES
456		});
457		DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
458			transform: transformCaseFunc,
459			base: DEFAULT_DATA_URI_TAGS
460		});
461		FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, { transform: transformCaseFunc });
462		FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), { transform: transformCaseFunc });
463		FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), { transform: transformCaseFunc });
464		USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
465		ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
466		ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
467		ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
468		ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
469		SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
470		SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
471		WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
472		RETURN_DOM = cfg.RETURN_DOM || false;
473		RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
474		RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
475		FORCE_BODY = cfg.FORCE_BODY || false;
476		SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
477		SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
478		KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
479		IN_PLACE = cfg.IN_PLACE || false;
480		IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
481		NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
482		MATHML_TEXT_INTEGRATION_POINTS = _resolveObjectOption(cfg, "MATHML_TEXT_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS));
483		HTML_INTEGRATION_POINTS = _resolveObjectOption(cfg, "HTML_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS));
484		const customElementHandling = _resolveObjectOption(cfg, "CUSTOM_ELEMENT_HANDLING", () => create(null));
485		CUSTOM_ELEMENT_HANDLING = create(null);
486		if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
487		if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
488		if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
489		seal(CUSTOM_ELEMENT_HANDLING);
490		if (SAFE_FOR_TEMPLATES) ALLOW_DATA_ATTR = false;
491		if (RETURN_DOM_FRAGMENT) RETURN_DOM = true;
492		if (USE_PROFILES) {
493			ALLOWED_TAGS = addToSet({}, text);
494			ALLOWED_ATTR = create(null);
495			if (USE_PROFILES.html === true) {
496				addToSet(ALLOWED_TAGS, html$1);
497				addToSet(ALLOWED_ATTR, html);
498			}
499			if (USE_PROFILES.svg === true) {
500				addToSet(ALLOWED_TAGS, svg$1);
501				addToSet(ALLOWED_ATTR, svg);
502				addToSet(ALLOWED_ATTR, xml);
503			}
504			if (USE_PROFILES.svgFilters === true) {
505				addToSet(ALLOWED_TAGS, svgFilters);
506				addToSet(ALLOWED_ATTR, svg);
507				addToSet(ALLOWED_ATTR, xml);
508			}
509			if (USE_PROFILES.mathMl === true) {
510				addToSet(ALLOWED_TAGS, mathMl$1);
511				addToSet(ALLOWED_ATTR, mathMl);
512				addToSet(ALLOWED_ATTR, xml);
513			}
514		}
515		EXTRA_ELEMENT_HANDLING.tagCheck = null;
516		EXTRA_ELEMENT_HANDLING.attributeCheck = null;
517		if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
518			if (typeof cfg.ADD_TAGS === "function") EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
519			else if (arrayIsArray(cfg.ADD_TAGS)) {
520				if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) ALLOWED_TAGS = clone(ALLOWED_TAGS);
521				addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
522			}
523		}
524		if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
525			if (typeof cfg.ADD_ATTR === "function") EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
526			else if (arrayIsArray(cfg.ADD_ATTR)) {
527				if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) ALLOWED_ATTR = clone(ALLOWED_ATTR);
528				addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
529			}
530		}
531		if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
532			if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
533			addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
534		}
535		if (KEEP_CONTENT) ALLOWED_TAGS["#text"] = true;
536		if (WHOLE_DOCUMENT) addToSet(ALLOWED_TAGS, [
537			"html",
538			"head",
539			"body"
540		]);
541		if (ALLOWED_TAGS.table) {
542			addToSet(ALLOWED_TAGS, ["tbody"]);
543			delete FORBID_TAGS.tbody;
544		}
545		if (cfg.TRUSTED_TYPES_POLICY) {
546			if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.");
547			if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.");
548			const previousTrustedTypesPolicy = trustedTypesPolicy;
549			trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
550			try {
551				emptyHTML = _createTrustedHTML("");
552			} catch (error) {
553				trustedTypesPolicy = previousTrustedTypesPolicy;
554				throw error;
555			}
556		} else if (cfg.TRUSTED_TYPES_POLICY === null) {
557			trustedTypesPolicy = void 0;
558			emptyHTML = "";
559		} else {
560			if (trustedTypesPolicy === void 0) trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
561			if (trustedTypesPolicy && typeof emptyHTML === "string") emptyHTML = _createTrustedHTML("");
562		}
563		if (freeze) freeze(cfg);
564		CONFIG = cfg;
565	};
566	const ALL_SVG_TAGS = addToSet({}, [
567		...svg$1,
568		...svgFilters,
569		...svgDisallowed
570	]);
571	const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
572	/**
573	* Namespace rules for an element in the SVG namespace.
574	*
575	* @param tagName the element's lowercase tag name
576	* @param parent the (possibly simulated) parent node
577	* @param parentTagName the parent's lowercase tag name
578	* @returns true if a spec-compliant parser could produce this element
579	*/
580	const _checkSvgNamespace = function _checkSvgNamespace(tagName, parent, parentTagName) {
581		if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "svg";
582		if (parent.namespaceURI === MATHML_NAMESPACE) return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
583		return Boolean(ALL_SVG_TAGS[tagName]);
584	};
585	/**
586	* Namespace rules for an element in the MathML namespace.
587	*
588	* @param tagName the element's lowercase tag name
589	* @param parent the (possibly simulated) parent node
590	* @param parentTagName the parent's lowercase tag name
591	* @returns true if a spec-compliant parser could produce this element
592	*/
593	const _checkMathMlNamespace = function _checkMathMlNamespace(tagName, parent, parentTagName) {
594		if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "math";
595		if (parent.namespaceURI === SVG_NAMESPACE) return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
596		return Boolean(ALL_MATHML_TAGS[tagName]);
597	};
598	/**
599	* Namespace rules for an element in the HTML namespace.
600	*
601	* @param tagName the element's lowercase tag name
602	* @param parent the (possibly simulated) parent node
603	* @param parentTagName the parent's lowercase tag name
604	* @returns true if a spec-compliant parser could produce this element
605	*/
606	const _checkHtmlNamespace = function _checkHtmlNamespace(tagName, parent, parentTagName) {
607		if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) return false;
608		if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) return false;
609		return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
610	};
611	/**
612	* @param element a DOM element whose namespace is being checked
613	* @returns Return false if the element has a
614	*  namespace that a spec-compliant parser would never
615	*  return. Return true otherwise.
616	*/
617	const _checkValidNamespace = function _checkValidNamespace(element) {
618		let parent = getParentNode(element);
619		if (!parent || !parent.tagName) parent = {
620			namespaceURI: NAMESPACE,
621			tagName: "template"
622		};
623		const tagName = stringToLowerCase(element.tagName);
624		const parentTagName = stringToLowerCase(parent.tagName);
625		if (!ALLOWED_NAMESPACES[element.namespaceURI]) return false;
626		if (element.namespaceURI === SVG_NAMESPACE) return _checkSvgNamespace(tagName, parent, parentTagName);
627		if (element.namespaceURI === MATHML_NAMESPACE) return _checkMathMlNamespace(tagName, parent, parentTagName);
628		if (element.namespaceURI === HTML_NAMESPACE) return _checkHtmlNamespace(tagName, parent, parentTagName);
629		if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) return true;
630		return false;
631	};
632	/**
633	* _forceRemove
634	*
635	* @param node a DOM node
636	*/
637	const _forceRemove = function _forceRemove(node) {
638		arrayPush(DOMPurify.removed, { element: node });
639		try {
640			getParentNode(node).removeChild(node);
641		} catch (_) {
642			remove(node);
643			if (!getParentNode(node)) throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
644		}
645	};
646	/**
647	* _stripAttributeNode
648	*
649	* Remove a single Attr node case/namespace-exactly on an attribute-teardown
650	* path. Name-based removeAttribute() ASCII-lowercases its lookup key for an
651	* HTML element in an HTML document and so silently misses a case-preserved
652	* handler (e.g. `ONERROR` off an XML/XHTML import) - the same defect
653	* _removeAttribute() was fixed for, which a name-based call would reintroduce
654	* on these IN_PLACE teardown paths. Unlike _removeAttribute this does not
655	* record into DOMPurify.removed: the neutralize passes intentionally do not
656	* book-keep. A clobbered/detached node falls back to best-effort name-based
657	* removal.
658	*
659	* @param element the element to strip the attribute from
660	* @param attribute the Attr node to remove
661	* @param name the attribute's name, for the fallback path
662	*/
663	const _stripAttributeNode = function _stripAttributeNode(element, attribute, name) {
664		try {
665			removeAttributeNode(element, attribute);
666		} catch (_) {
667			try {
668				element.removeAttribute(name);
669			} catch (_) {}
670		}
671	};
672	/**
673	* _neutralizeRoot
674	*
675	* Fail-closed teardown of an in-place root after the sanitize walk aborts
676	* (campaign-3 F2). An internal throw mid-walk — e.g. a page-registered
677	* custom element's reaction detaches a node so `_forceRemove`'s deliberate
678	* parentless guard throws, or any other re-entrant engine mutation — would
679	* otherwise leave the caller's *live* tree half-sanitized, with everything
680	* after the abort point still carrying its handlers. There is no safe way
681	* to resume the walk (the tree mutated under us), so we strip the root bare:
682	* remove every child and every attribute, then let the caller's catch see
683	* the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes`
684	* getters; the root was already clobber-pre-flighted at the IN_PLACE entry).
685	*
686	* @param root the in-place root to empty
687	*/
688	const _neutralizeRoot = function _neutralizeRoot(root) {
689		_neutralizeSubtree(root);
690		const childNodes = getChildNodes(root);
691		if (childNodes) {
692			const snapshot = [];
693			arrayForEach(childNodes, (child) => {
694				arrayPush(snapshot, child);
695			});
696			arrayForEach(snapshot, (child) => {
697				try {
698					remove(child);
699				} catch (_) {}
700			});
701		}
702		const attributes = getAttributes(root);
703		if (attributes) for (let i = attributes.length - 1; i >= 0; --i) {
704			const attribute = attributes[i];
705			const name = attribute && attribute.name;
706			if (typeof name === "string") _stripAttributeNode(root, attribute, name);
707		}
708	};
709	/**
710	* _removeAttribute
711	*
712	* Name-based getAttributeNode()/removeAttribute() ASCII-lowercase their
713	* lookup key for HTML elements in an HTML document, so they silently miss an
714	* attribute whose stored qualified name still contains uppercase ASCII
715	* letters. That happens when the node came from a case-preserving source
716	* (an XML/XHTML document imported via importNode(), or createAttributeNS()),
717	* where e.g. `ONERROR` survives the walk: the policy check lowercases to
718	* `onerror` and rejects it, but `removeAttribute('ONERROR')` looks up
719	* `onerror` and finds nothing. Remove the exact Attr node instead, which is
720	* case- and namespace-exact, and fall back to name-based removal only when
721	* the caller could not supply the node.
722	*
723	* @param name an Attribute name
724	* @param element a DOM node
725	* @param attr the exact Attr node to remove, when the caller has it
726	*/
727	const _removeAttribute = function _removeAttribute(name, element, attr) {
728		if (!attr) try {
729			attr = element.getAttributeNode(name);
730		} catch (_) {
731			attr = null;
732		}
733		arrayPush(DOMPurify.removed, {
734			attribute: attr || null,
735			from: element
736		});
737		try {
738			if (attr) removeAttributeNode(element, attr);
739			else element.removeAttribute(name);
740		} catch (_) {
741			try {
742				element.removeAttribute(name);
743			} catch (_) {}
744		}
745		if (name === "is") {
746			if (RETURN_DOM || RETURN_DOM_FRAGMENT) try {
747				_forceRemove(element);
748			} catch (_) {}
749			else try {
750				element.setAttribute(name, "");
751			} catch (_) {}
752		}
753	};
754	/**
755	* _stripDisallowedAttributes
756	*
757	* Removes every attribute the active configuration does not allow from a
758	* single element, using the same allowlist as the main attribute pass (so
759	* `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to
760	* neutralise nodes that are being discarded from an in-place tree.
761	*
762	* @param element the element to strip
763	*/
764	const _stripDisallowedAttributes = function _stripDisallowedAttributes(element) {
765		const attributes = getAttributes(element);
766		if (!attributes) return;
767		for (let i = attributes.length - 1; i >= 0; --i) {
768			const attribute = attributes[i];
769			const name = attribute && attribute.name;
770			if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue;
771			_stripAttributeNode(element, attribute, name);
772		}
773	};
774	/**
775	* _neutralizeSubtree
776	*
777	* Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT
778	* move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary,
779	* namespace, comment, processing-instruction and KEEP_CONTENT:false removals
780	* all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path
781	* those dropped nodes are detached from the caller's LIVE tree but a
782	* handler-bearing original among them (an `<img onerror>`/`<video>` that was
783	* loading) keeps its queued resource event, which fires in page scope after
784	* sanitize returns. This walks a removed subtree and strips every attribute
785	* the active configuration does not allow — so `on*` handlers are cancelled
786	* through the SAME allowlist that governs kept nodes, not a separate `/^on/`
787	* blocklist. Run synchronously before sanitize returns, i.e. before any
788	* queued event can fire. Hook-free by design: these nodes leave the output,
789	* so firing attribute hooks for them would be surprising. Clobber-safe reads;
790	* a doomed clobbered node may shadow `removeAttribute` (its own attributes are
791	* irrelevant — it is discarded — while its non-clobbered descendants, e.g.
792	* the `<img>`, are reached and scrubbed).
793	*
794	* @param root the root of a removed subtree to neutralise
795	*/
796	const _neutralizeSubtree = function _neutralizeSubtree(root) {
797		const stack = [root];
798		while (stack.length > 0) {
799			const node = stack.pop();
800			if (_readNodeType(node) === NODE_TYPE.element) _stripDisallowedAttributes(node);
801			const childNodes = getChildNodes(node);
802			if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
803		}
804	};
805	/**
806	* _neutralizePatchLinkage
807	*
808	* IN_PLACE entry pre-pass (declarative-partial-updates / streaming
809	* hardening, https://github.com/WICG/declarative-partial-updates).
810	*
811	* The main walk strips patch linkage (`for`/`patchsrc`) and removes range
812	* markers (PIs / markup comments) node-by-node, in document order, AS it
813	* reaches each node. On a live in-place root that leaves a window: from the
814	* moment the root is connected until the walk arrives at a given node, that
815	* node's linkage is live. A patch applied on connection/stream can fire as
816	* a microtask during the walk and inject or teleport an unsanitized DOM
817	* range into a region the iterator has already passed and will not revisit,
818	* so the post-return "tree is sanitized" contract is violated. Sweep the
819	* whole tree once up front and sever every linkage before the walk begins,
820	* closing that window.
821	*
822	* This CANNOT undo a patch that already fired before sanitize ran — that is
823	* the irreducible "do not IN_PLACE a live-connected attacker tree" caveat —
824	* but it closes everything from sanitize-start onward. Gated on SAFE_FOR_XML
825	* to group with the rest of the declarative-partial-updates handling and
826	* stay overridable, consistent with the codebase.
827	*
828	* Clobber-safe traversal (cached childNodes getter); per-node try/catch so a
829	* clobbered root cannot defeat the sweep of its non-clobbered descendants.
830	*
831	* NOTE (pending real-Chrome confirmation, see test/declarative-patch-probe
832	* .html Q1): this mirrors the existing policy of keeping `for` on
833	* <label>/<output>. If the shipping feature can drive a patch through a
834	* surviving `for`-on-label/output + `id` pair, this pre-pass and the
835	* attribute check at _isBasicCustomElement's caller must additionally drop
836	* that pair on the IN_PLACE path. Left as-is until the taxonomy is verified.
837	*
838	* @param root the in-place root to sweep
839	*/
840	/**
841	* Central policy for declarative-partial-updates patch-linkage attributes,
842	* shared by the _neutralizePatchLinkage pre-pass and _isValidAttribute so
843	* the two sites cannot drift: `patchsrc` always links, `for` links
844	* everywhere except on <label>/<output>, and the whole policy is gated on
845	* SAFE_FOR_XML (see the rationale block in _isValidAttribute).
846	*
847	* @param lcName the transformCaseFunc'd attribute name
848	* @param lcTag the transformCaseFunc'd tag name of the carrying element
849	* @return true if the attribute is patch linkage and must be dropped
850	*/
851	const _isPatchLinkageAttribute = function _isPatchLinkageAttribute(lcName, lcTag) {
852		if (!SAFE_FOR_XML) return false;
853		if (lcName === "patchsrc") return true;
854		return lcName === "for" && lcTag !== "label" && lcTag !== "output";
855	};
856	const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
857		if (!SAFE_FOR_XML) return;
858		const stack = [root];
859		while (stack.length > 0) {
860			const node = stack.pop();
861			const nodeType = _readNodeType(node);
862			if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
863				try {
864					remove(node);
865				} catch (_) {}
866				continue;
867			}
868			if (nodeType === NODE_TYPE.element) {
869				const element = node;
870				const lcTag = transformCaseFunc(_readNodeName(node));
871				try {
872					if (element.hasAttribute && element.hasAttribute("patchsrc")) element.removeAttribute("patchsrc");
873					if (element.hasAttribute && element.hasAttribute("for") && _isPatchLinkageAttribute("for", lcTag)) element.removeAttribute("for");
874				} catch (_) {}
875			}
876			const childNodes = getChildNodes(node);
877			if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
878		}
879	};
880	/**
881	* _initDocument
882	*
883	* @param dirty - a string of dirty markup
884	* @return a DOM, filled with the dirty markup
885	*/
886	const _initDocument = function _initDocument(dirty) {
887		let doc = null;
888		let leadingWhitespace = null;
889		if (FORCE_BODY) dirty = "<remove></remove>" + dirty;
890		else {
891			const matches = stringMatch(dirty, /^[\r\n\t ]+/);
892			leadingWhitespace = matches && matches[0];
893		}
894		if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) dirty = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>" + dirty + "</body></html>";
895		const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
896		if (NAMESPACE === HTML_NAMESPACE) try {
897			doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
898		} catch (_) {}
899		if (!doc || !doc.documentElement) {
900			doc = implementation.createDocument(NAMESPACE, "template", null);
901			try {
902				doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
903			} catch (_) {}
904		}
905		const body = doc.body || doc.documentElement;
906		if (dirty && leadingWhitespace) body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
907		if (NAMESPACE === HTML_NAMESPACE) return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
908		return WHOLE_DOCUMENT ? doc.documentElement : body;
909	};
910	/**
911	* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
912	*
913	* @param root The root element or node to start traversing on.
914	* @return The created NodeIterator
915	*/
916	const _createNodeIterator = function _createNodeIterator(root) {
917		const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;
918		return createNodeIterator.call(doc || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
919	};
920	/**
921	* Replace template expression syntax (mustache, ERB, template
922	* literal) with a space; shared by all SAFE_FOR_TEMPLATES scrub
923	* sites. Order matters: mustache, then ERB, then template literal.
924	*
925	* @param value the string to scrub
926	* @returns the scrubbed string
927	*/
928	const _stripTemplateExpressions = function _stripTemplateExpressions(value) {
929		value = stringReplace(value, MUSTACHE_EXPR$1, " ");
930		value = stringReplace(value, ERB_EXPR$1, " ");
931		value = stringReplace(value, TMPLIT_EXPR$1, " ");
932		return value;
933	};
934	/**
935	* Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the
936	* character data of an element subtree. Used as the final safety net for
937	* SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions
938	* which only form after text-node normalization (e.g. fragments split across
939	* stripped elements) cannot survive into a template-evaluating framework.
940	*
941	* Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`
942	* in place rather than round-tripping through innerHTML. This preserves
943	* descendant node references (important for IN_PLACE callers), avoids a
944	* serialize/reparse cycle, and reads literal character data — which means
945	* `<%...%>` in text content matches the ERB regex against its real bytes
946	* instead of the HTML-entity-escaped form innerHTML would produce.
947	*
948	* Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for
949	* attributes is performed during the per-node `_sanitizeAttributes` pass.
950	*
951	* @param node The root element whose character data should be scrubbed.
952	*/
953	const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
954		var _node$querySelectorAl;
955		node.normalize();
956		const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;
957		const walker = createNodeIterator.call(doc || node, node, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
958		let currentNode = walker.nextNode();
959		while (currentNode) {
960			currentNode.data = _stripTemplateExpressions(currentNode.data);
961			currentNode = walker.nextNode();
962		}
963		const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
964		if (templates) arrayForEach(templates, (tmpl) => {
965			if (_isDocumentFragment(tmpl.content)) _scrubTemplateExpressions2(tmpl.content);
966		});
967	};
968	/**
969	* _isClobbered
970	*
971	* Detect DOM-clobbering on HTMLFormElement nodes. Form is the only HTML
972	* interface with [LegacyOverrideBuiltIns]; a descendant element with a
973	* `name` attribute matching a prototype property shadows that property
974	* on direct reads. We use this check at the IN_PLACE entry-point and
975	* during attribute sanitization to refuse clobbered forms.
976	*
977	* @param element element to check for clobbering attacks
978	* @return true if clobbered, false if safe
979	*/
980	const _isClobbered = function _isClobbered(element) {
981		const realTagName = getNodeName ? getNodeName(element) : null;
982		if (typeof realTagName !== "string") return false;
983		if (transformCaseFunc(realTagName) !== "form") return false;
984		return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.removeAttributeNode !== "function" || typeof element.getAttributeNode !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || element.nodeType !== getNodeType(element) || element.childNodes !== getChildNodes(element);
985	};
986	/**
987	* Checks whether the given value is a DocumentFragment from any realm.
988	*
989	* The realm-independent replacement reads `nodeType` through the cached
990	* Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE
991	* constant (11). nodeType is a numeric value resolved from the node's
992	* internal slot, identical across realms for the same kind of node.
993	*
994	* @param value object to check
995	* @return true if value is a DocumentFragment-shaped node from any realm
996	*/
997	const _isDocumentFragment = function _isDocumentFragment(value) {
998		if (!getNodeType || typeof value !== "object" || value === null) return false;
999		try {
1000			return getNodeType(value) === NODE_TYPE.documentFragment;
1001		} catch (_) {
1002			return false;
1003		}
1004	};
1005	/**
1006	* Checks whether the given object is a DOM node, including nodes that
1007	* originate from a different window/realm (e.g. an iframe's
1008	* contentDocument). The previous `value instanceof Node` check was
1009	* realm-bound: nodes from a different window failed it, causing
1010	* sanitize() to silently stringify them and reset IN_PLACE to false,
1011	* returning the original node unsanitized. See GHSA-4w3q-35jp-p934.
1012	*
1013	* @param value object to check whether it's a DOM node
1014	* @return true if value is a DOM node from any realm
1015	*/
1016	const _isNode = function _isNode(value) {
1017		if (!getNodeType || typeof value !== "object" || value === null) return false;
1018		try {
1019			return typeof getNodeType(value) === "number";
1020		} catch (_) {
1021			return false;
1022		}
1023	};
1024	function _executeHooks(hooks, currentNode, data) {
1025		if (hooks.length === 0) return;
1026		arrayForEach(hooks, (hook) => {
1027			hook.call(DOMPurify, currentNode, data, CONFIG);
1028		});
1029	}
1030	/**
1031	* Structural-threat checks that condemn a node regardless of the
1032	* allowlists: mXSS via namespace confusion, risky CSS construction,
1033	* processing instructions, markup-bearing comments. Pure predicate;
1034	* the caller removes. Check order is load-bearing.
1035	*
1036	* @param currentNode the node to inspect
1037	* @param tagName the node's transformCaseFunc'd tag name
1038	* @return true if the node must be removed
1039	*/
1040	const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
1041		if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) return true;
1042		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))) return true;
1043		if (currentNode.nodeType === NODE_TYPE.processingInstruction) return true;
1044		if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) return true;
1045		return false;
1046	};
1047	/**
1048	* Evaluate a CUSTOM_ELEMENT_HANDLING check (a RegExp or a predicate
1049	* function, per the validation in _parseConfig) against a name.
1050	* Additional arguments are forwarded to predicate functions - the
1051	* attributeNameCheck predicate receives the tag name as its second
1052	* argument. A null/absent check never matches.
1053	*
1054	* @param check the configured tagNameCheck / attributeNameCheck value
1055	* @param name the name to test
1056	* @param args extra arguments forwarded to a predicate function
1057	* @return true if the check matches the name
1058	*/
1059	const _matchesNameCheck = function _matchesNameCheck(check, name) {
1060		if (check instanceof RegExp) return regExpTest(check, name);
1061		if (check instanceof Function) {
1062			for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
1063			return Boolean(check(name, ...args));
1064		}
1065		return false;
1066	};
1067	/**
1068	* Handle a node whose tag is forbidden or not allowlisted: keep
1069	* allowed custom elements (false return exits _sanitizeElements
1070	* early - the namespace and fallback-tag removal checks are
1071	* intentionally skipped for kept custom elements), else hoist
1072	* content per KEEP_CONTENT and remove.
1073	*
1074	* A kept custom element is the ONLY case in which this function
1075	* returns false, so the caller uses that return value to run the
1076	* afterSanitizeElements hook on the kept element and keep the
1077	* element-hook lifecycle consistent with normal allowlisted
1078	* elements (GHSA-c2j3-45gr-mqc4).
1079	*
1080	* @param currentNode the disallowed node
1081	* @param tagName the node's transformCaseFunc'd tag name
1082	* @return true if the node was removed, false if kept
1083	*/
1084	const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
1085		if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1086		if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1087			const parentNode = getParentNode(currentNode);
1088			const childNodes = getChildNodes(currentNode);
1089			if (childNodes && parentNode) {
1090				const childCount = childNodes.length;
1091				for (let i = childCount - 1; i >= 0; --i) {
1092					const hoisted = currentNode === root ? cloneNode(childNodes[i], true) : childNodes[i];
1093					parentNode.insertBefore(hoisted, getNextSibling(currentNode));
1094				}
1095			}
1096		}
1097		_forceRemove(currentNode);
1098		return true;
1099	};
1100	/**
1101	* Fork a hook-mutable allowlist off its shared binding the first time a
1102	* (possibly lazily-installed) uponSanitize* hook is about to see it, so the
1103	* hook cannot widen the per-instance default or the setConfig binding by
1104	* reference and leak past the call. Returns the set unchanged once it is
1105	* already call-local, so repeated calls across elements are idempotent.
1106	*
1107	* @param hookList the uponSanitize* hook array for this event
1108	* @param set the current ALLOWED_TAGS / ALLOWED_ATTR binding
1109	* @param defaultSet the per-instance DEFAULT_ALLOWED_* constant
1110	* @param setConfigSet the captured setConfig() binding, or null
1111	* @return a call-local clone if a hook is present and set is still shared,
1112	*   else set unchanged
1113	*/
1114	const _forkSharedAllowlist = function _forkSharedAllowlist(hookList, set, defaultSet, setConfigSet) {
1115		if (hookList.length === 0) return set;
1116		return set === defaultSet || set === setConfigSet ? clone(set) : set;
1117	};
1118	/**
1119	* Shared guard for a node that a hook has detached from the walk tree,
1120	* used after each element-hook site in _sanitizeElements. Detaching is a
1121	* long-standing user pattern (issue #469; draw.io-style foreignObject
1122	* filtering). Per the cached, unclobberable parentNode getter the node is
1123	* genuinely out of the tree, so it can reach neither the serialized
1124	* output nor an IN_PLACE live tree; treat it as removed and stop
1125	* processing it. Without this guard, the unsafe-node / namespace checks
1126	* would call _forceRemove on a parentless node and hit the REPORT-3
1127	* fail-closed throw — which exists for nodes DOMPurify wants gone but
1128	* *cannot* detach (clobbered / parentless roots), the opposite of a node
1129	* that is already safely gone. The walk root is exempt: a detached
1130	* IN_PLACE root is legitimate input and must still be fully sanitized,
1131	* and a kill-decision on it must keep hitting the REPORT-3 throw.
1132	*
1133	* Nodes detached by hooks stay the hook's responsibility for placement:
1134	* they are not recorded in DOMPurify.removed, so the post-walk IN_PLACE
1135	* pass (which iterates DOMPurify.removed) does not reach them. But a
1136	* hook-detached subtree can still hold a queued resource-event handler -
1137	* e.g. an <img onload> that began loading when the caller built the live
1138	* tree - which fires in page scope after sanitize returns even though the
1139	* handler never reached the returned tree. That is the audit-5 F1 hazard,
1140	* and the documented node.remove() hook pattern walks straight into it.
1141	* So on the IN_PLACE path we neutralize the detached subtree inline,
1142	* stripping its non-allow-listed attributes before returning, exactly as
1143	* the post-walk pass does for _forceRemove'd subtrees.
1144	*
1145	* @param currentNode the node a hook may have detached
1146	* @param root the current walk root
1147	* @return true if the node is detached and now handled, false otherwise
1148	*/
1149	const _handleHookDetachedNode = function _handleHookDetachedNode(currentNode, root) {
1150		if (currentNode === root || getParentNode(currentNode) !== null) return false;
1151		if (IN_PLACE) _neutralizeSubtree(currentNode);
1152		return true;
1153	};
1154	/**
1155	* _sanitizeElements
1156	*
1157	* @protect nodeName
1158	* @protect textContent
1159	* @protect removeChild
1160	* @param currentNode to check for permission to exist
1161	* @return true if node was killed, false if left alive
1162	*/
1163	const _sanitizeElements = function _sanitizeElements(currentNode, root) {
1164		_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
1165		if (_handleHookDetachedNode(currentNode, root)) return true;
1166		if (_isClobbered(currentNode)) {
1167			_forceRemove(currentNode);
1168			return true;
1169		}
1170		const tagName = transformCaseFunc(_readNodeName(currentNode));
1171		ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
1172		_executeHooks(hooks.uponSanitizeElement, currentNode, {
1173			tagName,
1174			allowedTags: ALLOWED_TAGS
1175		});
1176		if (_handleHookDetachedNode(currentNode, root)) return true;
1177		if (_isUnsafeNode(currentNode, tagName)) {
1178			_forceRemove(currentNode);
1179			return true;
1180		}
1181		if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
1182			const removed = _sanitizeDisallowedNode(currentNode, tagName, root);
1183			if (removed === false) 
vendor: 24,299 bytes, lines 1183-1953
1183_executeHooks(hooks.afterSanitizeElements, currentNode, null);
1184			return removed;
1185		}
1186		if (_readNodeType(currentNode) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
1187			_forceRemove(currentNode);
1188			return true;
1189		}
1190		if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
1191			_forceRemove(currentNode);
1192			return true;
1193		}
1194		if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1195			const content = _stripTemplateExpressions(currentNode.textContent);
1196			if (currentNode.textContent !== content) {
1197				arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
1198				currentNode.textContent = content;
1199			}
1200		}
1201		_executeHooks(hooks.afterSanitizeElements, currentNode, null);
1202		return false;
1203	};
1204	/**
1205	* _isValidAttribute
1206	*
1207	* @param lcTag Lowercase tag name of containing element.
1208	* @param lcName Lowercase attribute name.
1209	* @param value Attribute value.
1210	* @return Returns true if `value` is valid, otherwise false.
1211	*/
1212	const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1213		if (FORBID_ATTR[lcName]) return false;
1214		if (_isPatchLinkageAttribute(lcName, lcTag)) return false;
1215		if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) return false;
1216		const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
1217		if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) return true;
1218		if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) return true;
1219		if (!nameIsPermitted) return _isBasicCustomElement(lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName, lcTag) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value);
1220		if (URI_SAFE_ATTRIBUTES[lcName]) return true;
1221		if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
1222		if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) return true;
1223		if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
1224		return !value;
1225	};
1226	const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [
1227		"annotation-xml",
1228		"color-profile",
1229		"font-face",
1230		"font-face-format",
1231		"font-face-name",
1232		"font-face-src",
1233		"font-face-uri",
1234		"missing-glyph"
1235	]);
1236	/**
1237	* _isBasicCustomElement
1238	* checks if at least one dash is included in tagName, and it's not the first char
1239	* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
1240	*
1241	* @param tagName name of the tag of the node to sanitize
1242	* @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1243	*/
1244	const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1245		return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
1246	};
1247	/**
1248	* Wrap an attribute value in the matching Trusted Types object when
1249	* the active policy requires it. Namespaced attributes pass through
1250	* unchanged (no TT support yet, see
1251	* https://bugs.chromium.org/p/chromium/issues/detail?id=1305293).
1252	*
1253	* @param lcTag lowercase tag name of the containing element
1254	* @param lcName lowercase attribute name
1255	* @param namespaceURI the attribute's namespace, if any
1256	* @param value the attribute value to wrap
1257	* @return the value, wrapped when Trusted Types demand it
1258	*/
1259	const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value) {
1260		if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1261			case "TrustedHTML": return _createTrustedHTML(value);
1262			case "TrustedScriptURL": return _createTrustedScriptURL(value);
1263		}
1264		return value;
1265	};
1266	/**
1267	* Write a modified attribute value back onto the element. On
1268	* success, re-probe for clobbering introduced by the new value and
1269	* remove the element when found; otherwise, when this writeback is the
1270	* recreate half of the SANITIZE_NAMED_PROPS remove-and-recreate, pop the
1271	* removal entry that path recorded so it does not show as removed. On
1272	* failure, remove the attribute instead.
1273	*
1274	* Returns true only on a clean write (the value was set and the new value
1275	* introduced no clobbering). The caller uses that, together with its own
1276	* knowledge of whether this attribute pushed a DOMPurify.removed record, to
1277	* decide whether to pop that record. The pop must happen ONLY for the
1278	* named-prop remove-and-recreate; popping on any other value change (trim,
1279	* template scrubbing, Trusted Types) would consume an unrelated _forceRemove
1280	* subtree-cleanup record and let that detached subtree keep a live event
1281	* handler through the IN_PLACE neutralization pass (SO-001).
1282	*
1283	* @param currentNode the element carrying the attribute
1284	* @param name the attribute name as present on the element
1285	* @param namespaceURI the attribute's namespace, if any
1286	* @param value the new attribute value
1287	* @return true if the value was written without introducing clobbering
1288	*/
1289	const _setAttributeValue = function _setAttributeValue(currentNode, name, namespaceURI, value) {
1290		try {
1291			if (namespaceURI) currentNode.setAttributeNS(namespaceURI, name, value);
1292			else currentNode.setAttribute(name, value);
1293			if (_isClobbered(currentNode)) {
1294				_forceRemove(currentNode);
1295				return false;
1296			}
1297			return true;
1298		} catch (_) {
1299			_removeAttribute(name, currentNode);
1300			return false;
1301		}
1302	};
1303	/**
1304	* _sanitizeAttributes
1305	*
1306	* @protect attributes
1307	* @protect nodeName
1308	* @protect removeAttribute
1309	* @protect setAttribute
1310	*
1311	* @param currentNode to sanitize
1312	*/
1313	const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1314		_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
1315		const attributes = currentNode.attributes;
1316		if (!attributes || _isClobbered(currentNode)) return;
1317		ALLOWED_ATTR = _forkSharedAllowlist(hooks.uponSanitizeAttribute, ALLOWED_ATTR, DEFAULT_ALLOWED_ATTR, SET_CONFIG_ALLOWED_ATTR);
1318		const hookEvent = {
1319			attrName: "",
1320			attrValue: "",
1321			keepAttr: true,
1322			allowedAttributes: ALLOWED_ATTR,
1323			forceKeepAttr: void 0
1324		};
1325		let l = attributes.length;
1326		const lcTag = transformCaseFunc(currentNode.nodeName);
1327		while (l--) {
1328			const attr = attributes[l];
1329			const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
1330			const lcName = transformCaseFunc(name);
1331			const initValue = attrValue;
1332			let value = name === "value" ? initValue : stringTrim(initValue);
1333			let recreatedNamedProp = false;
1334			hookEvent.attrName = lcName;
1335			hookEvent.attrValue = value;
1336			hookEvent.keepAttr = true;
1337			hookEvent.forceKeepAttr = void 0;
1338			_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
1339			value = hookEvent.attrValue;
1340			if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
1341				_removeAttribute(name, currentNode, attr);
1342				value = SANITIZE_NAMED_PROPS_PREFIX + value;
1343				recreatedNamedProp = true;
1344			}
1345			if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
1346				_removeAttribute(name, currentNode, attr);
1347				continue;
1348			}
1349			if (lcName === "attributename" && stringMatch(value, "href")) {
1350				_removeAttribute(name, currentNode, attr);
1351				continue;
1352			}
1353			if (hookEvent.forceKeepAttr) continue;
1354			if (!hookEvent.keepAttr) {
1355				_removeAttribute(name, currentNode, attr);
1356				continue;
1357			}
1358			if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
1359				_removeAttribute(name, currentNode, attr);
1360				continue;
1361			}
1362			if (SAFE_FOR_TEMPLATES) value = _stripTemplateExpressions(value);
1363			if (!_isValidAttribute(lcTag, lcName, value)) {
1364				_removeAttribute(name, currentNode, attr);
1365				continue;
1366			}
1367			value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
1368			if (value !== initValue) {
1369				if (_setAttributeValue(currentNode, name, namespaceURI, value) && recreatedNamedProp) arrayPop(DOMPurify.removed);
1370			}
1371		}
1372		_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
1373	};
1374	/**
1375	* _sanitizeShadowDOM
1376	*
1377	* @param fragment to iterate over recursively
1378	*/
1379	const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
1380		let shadowNode = null;
1381		const shadowIterator = _createNodeIterator(fragment);
1382		_executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
1383		while (shadowNode = shadowIterator.nextNode()) {
1384			_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
1385			_sanitizeElements(shadowNode, fragment);
1386			_sanitizeAttributes(shadowNode);
1387			if (_isDocumentFragment(shadowNode.content)) _sanitizeShadowDOM2(shadowNode.content);
1388			if (_readNodeType(shadowNode) === NODE_TYPE.element) {
1389				const innerSr = getShadowRoot(shadowNode);
1390				if (_isDocumentFragment(innerSr)) {
1391					_sanitizeAttachedShadowRoots(innerSr);
1392					_sanitizeShadowDOM2(innerSr);
1393				}
1394			}
1395		}
1396		_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
1397	};
1398	/**
1399	* _sanitizeAttachedShadowRoots
1400	*
1401	* Walks `root` and feeds every attached shadow root we encounter into
1402	* the existing _sanitizeShadowDOM pipeline. The default node iterator
1403	* does not descend into shadow trees, so nodes inside an attached
1404	* shadow root would otherwise be skipped entirely.
1405	*
1406	* Two real input paths put attached shadow roots in front of us:
1407	*   1. IN_PLACE on a DOM node that already has shadow roots attached.
1408	*   2. DOM-node input where importNode(dirty, true) deep-clones the
1409	*      shadow root because it was created with `clonable: true`.
1410	*
1411	* This pass runs once, up front, so the main iteration loop (and the
1412	* existing _sanitizeShadowDOM template-content recursion) stay
1413	* untouched — string-input paths are not affected.
1414	*
1415	* @param root the subtree root to walk for attached shadow roots
1416	*/
1417	const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots(root) {
1418		const stack = [{
1419			node: root,
1420			shadow: null
1421		}];
1422		while (stack.length > 0) {
1423			const item = stack.pop();
1424			if (item.shadow) {
1425				_sanitizeShadowDOM2(item.shadow);
1426				continue;
1427			}
1428			const node = item.node;
1429			const isElement = _readNodeType(node) === NODE_TYPE.element;
1430			const childNodes = getChildNodes(node);
1431			if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push({
1432				node: childNodes[i],
1433				shadow: null
1434			});
1435			if (isElement) {
1436				const rootName = getNodeName ? getNodeName(node) : null;
1437				if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
1438					const content = node.content;
1439					if (_isDocumentFragment(content)) stack.push({
1440						node: content,
1441						shadow: null
1442					});
1443				}
1444			}
1445			if (isElement) {
1446				const sr = getShadowRoot(node);
1447				if (_isDocumentFragment(sr)) stack.push({
1448					node: null,
1449					shadow: sr
1450				}, {
1451					node: sr,
1452					shadow: null
1453				});
1454			}
1455		}
1456	};
1457	DOMPurify.sanitize = function(dirty) {
1458		let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
1459		let body = null;
1460		let importedNode = null;
1461		let currentNode = null;
1462		let returnNode = null;
1463		IS_EMPTY_INPUT = !dirty;
1464		if (IS_EMPTY_INPUT) dirty = "<!-->";
1465		if (typeof dirty !== "string" && !_isNode(dirty)) {
1466			dirty = stringifyValue(dirty);
1467			if (typeof dirty !== "string") throw typeErrorCreate("dirty is not a string, aborting");
1468		}
1469		if (!DOMPurify.isSupported) return dirty;
1470		if (SET_CONFIG) {
1471			ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
1472			ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
1473		} else _parseConfig(cfg);
1474		if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) ALLOWED_TAGS = clone(ALLOWED_TAGS);
1475		if (hooks.uponSanitizeAttribute.length > 0) ALLOWED_ATTR = clone(ALLOWED_ATTR);
1476		DOMPurify.removed = [];
1477		const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
1478		if (inPlace) {
1479			_neutralizePatchLinkage(dirty);
1480			const nn = _readNodeName(dirty);
1481			if (typeof nn === "string") {
1482				const tagName = transformCaseFunc(nn);
1483				if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1484					_neutralizeRoot(dirty);
1485					throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
1486				}
1487			}
1488			if (_isClobbered(dirty)) {
1489				_neutralizeRoot(dirty);
1490				throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
1491			}
1492			try {
1493				_sanitizeAttachedShadowRoots(dirty);
1494			} catch (error) {
1495				_neutralizeRoot(dirty);
1496				throw error;
1497			}
1498		} else if (_isNode(dirty)) {
1499			body = _initDocument("<!---->");
1500			importedNode = body.ownerDocument.importNode(dirty, true);
1501			if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") body = importedNode;
1502			else if (importedNode.nodeName === "HTML") body = importedNode;
1503			else body.appendChild(importedNode);
1504			_sanitizeAttachedShadowRoots(body);
1505		} else {
1506			if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && dirty.indexOf("<") === -1) return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
1507			body = _initDocument(dirty);
1508			if (!body) return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
1509		}
1510		if (body && FORCE_BODY) _forceRemove(body.firstChild);
1511		const walkRoot = inPlace ? dirty : body;
1512		try {
1513			const nodeIterator = _createNodeIterator(walkRoot);
1514			while (currentNode = nodeIterator.nextNode()) {
1515				_sanitizeElements(currentNode, walkRoot);
1516				_sanitizeAttributes(currentNode);
1517				if (_isDocumentFragment(currentNode.content)) _sanitizeShadowDOM2(currentNode.content);
1518			}
1519		} catch (error) {
1520			if (inPlace) {
1521				_neutralizeRoot(dirty);
1522				arrayForEach(DOMPurify.removed, (entry) => {
1523					if (entry.element) _neutralizeSubtree(entry.element);
1524				});
1525			}
1526			throw error;
1527		}
1528		if (inPlace) {
1529			arrayForEach(DOMPurify.removed, (entry) => {
1530				if (entry.element) _neutralizeSubtree(entry.element);
1531			});
1532			if (SAFE_FOR_TEMPLATES) _scrubTemplateExpressions2(dirty);
1533			return dirty;
1534		}
1535		if (RETURN_DOM) {
1536			if (SAFE_FOR_TEMPLATES) _scrubTemplateExpressions2(body);
1537			if (RETURN_DOM_FRAGMENT) {
1538				returnNode = createDocumentFragment.call(body.ownerDocument);
1539				while (body.firstChild) returnNode.appendChild(body.firstChild);
1540			} else returnNode = body;
1541			if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) returnNode = importNode.call(originalDocument, returnNode, true);
1542			return returnNode;
1543		}
1544		let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
1545		if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
1546		if (SAFE_FOR_TEMPLATES) serializedHTML = _stripTemplateExpressions(serializedHTML);
1547		return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
1548	};
1549	DOMPurify.setConfig = function() {
1550		let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
1551		_parseConfig(cfg);
1552		SET_CONFIG = true;
1553		SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
1554		SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
1555	};
1556	DOMPurify.clearConfig = function() {
1557		CONFIG = null;
1558		SET_CONFIG = false;
1559		SET_CONFIG_ALLOWED_TAGS = null;
1560		SET_CONFIG_ALLOWED_ATTR = null;
1561		trustedTypesPolicy = defaultTrustedTypesPolicy;
1562		emptyHTML = "";
1563	};
1564	DOMPurify.isValidAttribute = function(tag, attr, value) {
1565		if (!CONFIG) _parseConfig({});
1566		const lcTag = transformCaseFunc(tag);
1567		const lcName = transformCaseFunc(attr);
1568		return _isValidAttribute(lcTag, lcName, value);
1569	};
1570	DOMPurify.addHook = function(entryPoint, hookFunction) {
1571		if (typeof hookFunction !== "function") return;
1572		if (!objectHasOwnProperty(hooks, entryPoint)) return;
1573		arrayPush(hooks[entryPoint], hookFunction);
1574	};
1575	DOMPurify.removeHook = function(entryPoint, hookFunction) {
1576		if (!objectHasOwnProperty(hooks, entryPoint)) return;
1577		if (hookFunction !== void 0) {
1578			const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
1579			return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
1580		}
1581		return arrayPop(hooks[entryPoint]);
1582	};
1583	DOMPurify.removeHooks = function(entryPoint) {
1584		if (!objectHasOwnProperty(hooks, entryPoint)) return;
1585		hooks[entryPoint] = [];
1586	};
1587	DOMPurify.removeAllHooks = function() {
1588		hooks = _createHooksMap();
1589	};
1590	return DOMPurify;
1591}
1592var entries, setPrototypeOf, isFrozen, getPrototypeOf, getOwnPropertyDescriptor, freeze, seal, create, _ref, apply, construct, arrayForEach, arrayLastIndexOf, arrayPop, arrayPush, arraySplice, arrayIsArray, stringToLowerCase, stringToString, stringMatch, stringReplace, stringIndexOf, stringTrim, numberToString, booleanToString, bigintToString, symbolToString, objectHasOwnProperty, objectToString, regExpTest, typeErrorCreate, html$1, svg$1, svgFilters, svgDisallowed, mathMl$1, mathMlDisallowed, text, html, svg, mathMl, xml, MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR, DATA_ATTR, ARIA_ATTR, IS_ALLOWED_URI, IS_SCRIPT_OR_DATA, ATTR_WHITESPACE, DOCTYPE_NAME, CUSTOM_ELEMENT, ELEMENT_MARKUP_PROBE, COMMENT_MARKUP_PROBE, FALLBACK_TAG_CLOSE, SELF_CLOSING_TAG, NODE_TYPE, LITERAL_TEXT_ELEMENT_NAMES, LITERAL_TEXT_ELEMENTS, LITERAL_TEXT_CLOSE, getGlobal, _createTrustedTypesPolicy, _createHooksMap, _resolveSetOption, _resolveObjectOption, purify;
1593function init_purify_es() {
1594	return (init_purify_es = __esmMin((() => {
1595		entries = Object.entries;
1596		setPrototypeOf = Object.setPrototypeOf;
1597		isFrozen = Object.isFrozen;
1598		getPrototypeOf = Object.getPrototypeOf;
1599		getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1600		freeze = Object.freeze;
1601		seal = Object.seal;
1602		create = Object.create;
1603		_ref = typeof Reflect !== "undefined" && Reflect;
1604		apply = _ref.apply;
1605		construct = _ref.construct;
1606		if (!freeze) freeze = function freeze(x) {
1607			return x;
1608		};
1609		if (!seal) seal = function seal(x) {
1610			return x;
1611		};
1612		if (!apply) apply = function apply(func, thisArg) {
1613			for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
1614			return func.apply(thisArg, args);
1615		};
1616		if (!construct) construct = function construct(Func) {
1617			for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) args[_key2 - 1] = arguments[_key2];
1618			return new Func(...args);
1619		};
1620		arrayForEach = unapply(Array.prototype.forEach);
1621		arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
1622		arrayPop = unapply(Array.prototype.pop);
1623		arrayPush = unapply(Array.prototype.push);
1624		arraySplice = unapply(Array.prototype.splice);
1625		arrayIsArray = Array.isArray;
1626		stringToLowerCase = unapply(String.prototype.toLowerCase);
1627		stringToString = unapply(String.prototype.toString);
1628		stringMatch = unapply(String.prototype.match);
1629		stringReplace = unapply(String.prototype.replace);
1630		stringIndexOf = unapply(String.prototype.indexOf);
1631		stringTrim = unapply(String.prototype.trim);
1632		numberToString = unapply(Number.prototype.toString);
1633		booleanToString = unapply(Boolean.prototype.toString);
1634		bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
1635		symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
1636		objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
1637		objectToString = unapply(Object.prototype.toString);
1638		regExpTest = unapply(RegExp.prototype.test);
1639		typeErrorCreate = unconstruct(TypeError);
1640		html$1 = freeze([
1641			"a",
1642			"abbr",
1643			"acronym",
1644			"address",
1645			"area",
1646			"article",
1647			"aside",
1648			"audio",
1649			"b",
1650			"bdi",
1651			"bdo",
1652			"big",
1653			"blink",
1654			"blockquote",
1655			"body",
1656			"br",
1657			"button",
1658			"canvas",
1659			"caption",
1660			"center",
1661			"cite",
1662			"code",
1663			"col",
1664			"colgroup",
1665			"content",
1666			"data",
1667			"datalist",
1668			"dd",
1669			"decorator",
1670			"del",
1671			"details",
1672			"dfn",
1673			"dialog",
1674			"dir",
1675			"div",
1676			"dl",
1677			"dt",
1678			"element",
1679			"em",
1680			"fieldset",
1681			"figcaption",
1682			"figure",
1683			"font",
1684			"footer",
1685			"form",
1686			"h1",
1687			"h2",
1688			"h3",
1689			"h4",
1690			"h5",
1691			"h6",
1692			"head",
1693			"header",
1694			"hgroup",
1695			"hr",
1696			"html",
1697			"i",
1698			"img",
1699			"input",
1700			"ins",
1701			"kbd",
1702			"label",
1703			"legend",
1704			"li",
1705			"main",
1706			"map",
1707			"mark",
1708			"marquee",
1709			"menu",
1710			"menuitem",
1711			"meter",
1712			"nav",
1713			"nobr",
1714			"ol",
1715			"optgroup",
1716			"option",
1717			"output",
1718			"p",
1719			"picture",
1720			"pre",
1721			"progress",
1722			"q",
1723			"rp",
1724			"rt",
1725			"ruby",
1726			"s",
1727			"samp",
1728			"search",
1729			"section",
1730			"select",
1731			"shadow",
1732			"slot",
1733			"small",
1734			"source",
1735			"spacer",
1736			"span",
1737			"strike",
1738			"strong",
1739			"style",
1740			"sub",
1741			"summary",
1742			"sup",
1743			"table",
1744			"tbody",
1745			"td",
1746			"template",
1747			"textarea",
1748			"tfoot",
1749			"th",
1750			"thead",
1751			"time",
1752			"tr",
1753			"track",
1754			"tt",
1755			"u",
1756			"ul",
1757			"var",
1758			"video",
1759			"wbr"
1760		]);
1761		svg$1 = freeze([
1762			"svg",
1763			"a",
1764			"altglyph",
1765			"altglyphdef",
1766			"altglyphitem",
1767			"animatecolor",
1768			"animatemotion",
1769			"animatetransform",
1770			"circle",
1771			"clippath",
1772			"defs",
1773			"desc",
1774			"ellipse",
1775			"enterkeyhint",
1776			"exportparts",
1777			"filter",
1778			"font",
1779			"g",
1780			"glyph",
1781			"glyphref",
1782			"hkern",
1783			"image",
1784			"inputmode",
1785			"line",
1786			"lineargradient",
1787			"marker",
1788			"mask",
1789			"metadata",
1790			"mpath",
1791			"part",
1792			"path",
1793			"pattern",
1794			"polygon",
1795			"polyline",
1796			"radialgradient",
1797			"rect",
1798			"stop",
1799			"style",
1800			"switch",
1801			"symbol",
1802			"text",
1803			"textpath",
1804			"title",
1805			"tref",
1806			"tspan",
1807			"view",
1808			"vkern"
1809		]);
1810		svgFilters = freeze([
1811			"feBlend",
1812			"feColorMatrix",
1813			"feComponentTransfer",
1814			"feComposite",
1815			"feConvolveMatrix",
1816			"feDiffuseLighting",
1817			"feDisplacementMap",
1818			"feDistantLight",
1819			"feDropShadow",
1820			"feFlood",
1821			"feFuncA",
1822			"feFuncB",
1823			"feFuncG",
1824			"feFuncR",
1825			"feGaussianBlur",
1826			"feImage",
1827			"feMerge",
1828			"feMergeNode",
1829			"feMorphology",
1830			"feOffset",
1831			"fePointLight",
1832			"feSpecularLighting",
1833			"feSpotLight",
1834			"feTile",
1835			"feTurbulence"
1836		]);
1837		svgDisallowed = freeze([
1838			"animate",
1839			"color-profile",
1840			"cursor",
1841			"discard",
1842			"font-face",
1843			"font-face-format",
1844			"font-face-name",
1845			"font-face-src",
1846			"font-face-uri",
1847			"foreignobject",
1848			"hatch",
1849			"hatchpath",
1850			"mesh",
1851			"meshgradient",
1852			"meshpatch",
1853			"meshrow",
1854			"missing-glyph",
1855			"script",
1856			"set",
1857			"solidcolor",
1858			"unknown",
1859			"use"
1860		]);
1861		mathMl$1 = freeze([
1862			"math",
1863			"menclose",
1864			"merror",
1865			"mfenced",
1866			"mfrac",
1867			"mglyph",
1868			"mi",
1869			"mlabeledtr",
1870			"mmultiscripts",
1871			"mn",
1872			"mo",
1873			"mover",
1874			"mpadded",
1875			"mphantom",
1876			"mroot",
1877			"mrow",
1878			"ms",
1879			"mspace",
1880			"msqrt",
1881			"mstyle",
1882			"msub",
1883			"msup",
1884			"msubsup",
1885			"mtable",
1886			"mtd",
1887			"mtext",
1888			"mtr",
1889			"munder",
1890			"munderover",
1891			"mprescripts"
1892		]);
1893		mathMlDisallowed = freeze([
1894			"maction",
1895			"maligngroup",
1896			"malignmark",
1897			"mlongdiv",
1898			"mscarries",
1899			"mscarry",
1900			"msgroup",
1901			"mstack",
1902			"msline",
1903			"msrow",
1904			"semantics",
1905			"annotation",
1906			"annotation-xml",
1907			"mprescripts",
1908			"none"
1909		]);
1910		text = freeze(["#text"]);
1911		html = freeze([
1912			"accept",
1913			"action",
1914			"align",
1915			"alt",
1916			"autocapitalize",
1917			"autocomplete",
1918			"autopictureinpicture",
1919			"autoplay",
1920			"background",
1921			"bgcolor",
1922			"border",
1923			"capture",
1924			"cellpadding",
1925			"cellspacing",
1926			"checked",
1927			"cite",
1928			"class",
1929			"clear",
1930			"color",
1931			"cols",
1932			"colspan",
1933			"command",
1934			"commandfor",
1935			"controls",
1936			"controlslist",
1937			"coords",
1938			"crossorigin",
1939			"datetime",
1940			"decoding",
1941			"default",
1942			"dir",
1943			"disabled",
1944			"disablepictureinpicture",
1945			"disableremoteplayback",
1946			"download",
1947			"draggable",
1948			"enctype",
1949			"enterkeyhint",
1950			"exportparts",
1951			"face",
1952			"for",
1953			"headers",
1954			"height",
1955			"hidden",
1956			"high",
1957			"href",
1958			"hreflang",
1959			"id",
1960			"inert",
1961			"inputmode",
1962			"integrity",
1963			"ismap",
1964			"kind",
1965			"label",
1966			"lang",
1967			"list",
1968			"loading",
1969			"loop",
1970			"low",
1971			"max",
1972			"maxlength",
1973			"media",
1974			"method",
1975			"min",
1976			"minlength",
1977			"multiple",
1978			"muted",
1979			"name",
1980			"nonce",
1981			"noshade",
1982			"novalidate",
1983			"nowrap",
1984			"open",
1985			"optimum",
1986			"part",
1987			"pattern",
1988			"placeholder",
1989			"playsinline",
1990			"popover",
1991			"popovertarget",
1992			"popovertargetaction",
1993			"poster",
1994			"preload",
1995			"pubdate",
1996			"radiogroup",
1997			"readonly",
1998			"rel",
1999			"required",
2000			"rev",
2001			"reversed",
2002			"role",
2003			"rows",
2004			"rowspan",
2005			"spellcheck",
2006			"scope",
2007			"selected",
2008			"shape",
2009			"size",
2010			"sizes",
2011			"slot",
2012			"span",
2013			"srclang",
2014			"start",
2015			"src",
2016			"srcset",
2017			"step",
2018			"style",
2019			"summary",
2020			"tabindex",
2021			"title",
2022			"translate",
2023			"type",
2024			"usemap",
2025			"valign",
2026			"value",
2027			"width",
2028			"wrap",
2029			"xmlns"
2030		]);
2031		svg = freeze([
2032			"accent-height",
2033			"accumulate",
2034			"additive",
2035			"alignment-baseline",
2036			"amplitude",
2037			"ascent",
2038			"attributename",
2039			"attributetype",
2040			"azimuth",
2041			"basefrequency",
2042			"baseline-shift",
2043			"begin",
2044			"bias",
2045			"by",
2046			"class",
2047			"clip",
2048			"clippathunits",
2049			"clip-path",
2050			"clip-rule",
2051			"color",
2052			"color-interpolation",
2053			"color-interpolation-filters",
2054			"color-profile",
2055			"color-rendering",
2056			"cx",
2057			"cy",
2058			"d",
2059			"dx",
2060			"dy",
2061			"diffuseconstant",
2062			"direction",
2063			"display",
2064			"divisor",
2065			"dominant-baseline",
2066			"dur",
2067			"edgemode",
2068			"elevation",
2069			"end",
2070			"exponent",
2071			"fill",
2072			"fill-opacity",
2073			"fill-rule",
2074			"filter",
2075			"filterunits",
2076			"flood-color",
2077			"flood-opacity",
2078			"font-family",
2079			"font-size",
2080			"font-size-adjust",
2081			"font-stretch",
2082			"font-style",
2083			"font-variant",
2084			"font-weight",
2085			"fx",
2086			"fy",
2087			"g1",
2088			"g2",
2089			"glyph-name",
2090			"glyphref",
2091			"gradientunits",
2092			"gradienttransform",
2093			"height",
2094			"href",
2095			"id",
2096			"image-rendering",
2097			"in",
2098			"in2",
2099			"intercept",
2100			"k",
2101			"k1",
2102			"k2",
2103			"k3",
2104			"k4",
2105			"kerning",
2106			"keypoints",
2107			"keysplines",
2108			"keytimes",
2109			"lang",
2110			"lengthadjust",
2111			"letter-spacing",
2112			"kernelmatrix",
2113			"kernelunitlength",
2114			"lighting-color",
2115			"local",
2116			"marker-end",
2117			"marker-mid",
2118			"marker-start",
2119			"markerheight",
2120			"markerunits",
2121			"markerwidth",
2122			"maskcontentunits",
2123			"maskunits",
2124			"max",
2125			"mask",
2126			"mask-type",
2127			"media",
2128			"method",
2129			"mode",
2130			"min",
2131			"name",
2132			"numoctaves",
2133			"offset",
2134			"operator",
2135			"opacity",
2136			"order",
2137			"orient",
2138			"orientation",
2139			"origin",
2140			"overflow",
2141			"paint-order",
2142			"path",
2143			"pathlength",
2144			"patterncontentunits",
2145			"patterntransform",
2146			"patternunits",
2147			"pointer-events",
2148			"points",
2149			"preservealpha",
2150			"preserveaspectratio",
2151			"primitiveunits",
2152			"r",
2153			"rx",
2154			"ry",
2155			"radius",
2156			"refx",
2157			"refy",
2158			"repeatcount",
2159			"repeatdur",
2160			"restart",
2161			"result",
2162			"rotate",
2163			"scale",
2164			"seed",
2165			"shape-rendering",
2166			"slope",
2167			"specularconstant",
2168			"specularexponent",
2169			"spreadmethod",
2170			"startoffset",
2171			"stddeviation",
2172			"stitchtiles",
2173			"stop-color",
2174			"stop-opacity",
2175			"stroke-dasharray",
2176			"stroke-dashoffset",
2177			"stroke-linecap",
2178			"stroke-linejoin",
2179			"stroke-miterlimit",
2180			"stroke-opacity",
2181			"stroke",
2182			"stroke-width",
2183			"style",
2184			"surfacescale",
2185			"systemlanguage",
2186			"tabindex",
2187			"tablevalues",
2188			"targetx",
2189			"targety",
2190			"transform",
2191			"transform-origin",
2192			"text-anchor",
2193			"text-decoration",
2194			"text-orientation",
2195			"text-rendering",
2196			"textlength",
2197			"type",
2198			"u1",
2199			"u2",
2200			"unicode",
2201			"values",
2202			"vector-effect",
2203			"viewbox",
2204			"visibility",
2205			"version",
2206			"vert-adv-y",
2207			"vert-origin-x",
2208			"vert-origin-y",
2209			"width",
2210			"word-spacing",
2211			"wrap",
2212			"writing-mode",
2213			"xchannelselector",
2214			"ychannelselector",
2215			"x",
2216			"x1",
2217			"x2",
2218			"xmlns",
2219			"y",
2220			"y1",
2221			"y2",
2222			"z",
2223			"zoomandpan"
2224		]);
2225		mathMl = freeze([
2226			"accent",
2227			"accentunder",
2228			"align",
2229			"bevelled",
2230			"close",
2231			"columnalign",
2232			"columnlines",
2233			"columnspacing",
2234			"columnspan",
2235			"denomalign",
2236			"depth",
2237			"dir",
2238			"display",
2239			"displaystyle",
2240			"encoding",
2241			"fence",
2242			"frame",
2243			"height",
2244			"href",
2245			"id",
2246			"largeop",
2247			"length",
2248			"linethickness",
2249			"lquote",
2250			"lspace",
2251			"mathbackground",
2252			"mathcolor",
2253			"mathsize",
2254			"mathvariant",
2255			"maxsize",
2256			"minsize",
2257			"movablelimits",
2258			"notation",
2259			"numalign",
2260			"open",
2261			"rowalign",
2262			"rowlines",
2263			"rowspacing",
2264			"rowspan",
2265			"rspace",
2266			"rquote",
2267			"scriptlevel",
2268			"scriptminsize",
2269			"scriptsizemultiplier",
2270			"selection",
2271			"separator",
2272			"separators",
2273			"stretchy",
2274			"subscriptshift",
2275			"supscriptshift",
2276			"symmetric",
2277			"voffset",
2278			"width",
2279			"xmlns"
2280		]);
2281		xml = freeze([
2282			"xlink:href",
2283			"xml:id",
2284			"xlink:title",
2285			"xml:space",
2286			"xmlns:xlink"
2287		]);
2288		MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
2289		ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
2290		TMPLIT_EXPR = seal(/\${[\w\W]*/g);
2291		DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
2292		ARIA_ATTR = seal(/^aria-[\-\w]+$/);
2293		IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i);
2294		IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
2295		ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g);
2296		DOCTYPE_NAME = seal(/^html$/i);
2297		CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
2298		ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
2299		COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
2300		FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
2301		SELF_CLOSING_TAG = seal(/\/>/i);
2302		NODE_TYPE = {
2303			element: 1,
2304			attribute: 2,
2305			text: 3,
2306			cdataSection: 4,
2307			entityReference: 5,
2308			entityNode: 6,
2309			processingInstruction: 7,
2310			comment: 8,
2311			document: 9,
2312			documentType: 10,
2313			documentFragment: 11,
2314			notation: 12
2315		};
2316		LITERAL_TEXT_ELEMENT_NAMES = [
2317			"style",
2318			"script",
2319			"xmp",
2320			"iframe",
2321			"noembed",
2322			"noframes",
2323			"plaintext",
2324			"noscript"
2325		];
2326		LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
2327		LITERAL_TEXT_CLOSE = function() {
2328			const map = {};
2329			arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
2330				map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
2331			});
2332			return freeze(map);
2333		}();
2334		getGlobal = function getGlobal() {
2335			return typeof window === "undefined" ? null : window;
2336		};
2337		_createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
2338			if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") return null;
2339			let suffix = null;
2340			const ATTR_NAME = "data-tt-policy-suffix";
2341			if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) suffix = purifyHostElement.getAttribute(ATTR_NAME);
2342			const policyName = "dompurify" + (suffix ? "#" + suffix : "");
2343			try {
2344				return trustedTypes.createPolicy(policyName, {
2345					createHTML(html) {
2346						return html;
2347					},
2348					createScriptURL(scriptUrl) {
2349						return scriptUrl;
2350					}
2351				});
2352			} catch (_) {
2353				console.warn("TrustedTypes policy " + policyName + " could not be created.");
2354				return null;
2355			}
2356		};
2357		_createHooksMap = function _createHooksMap() {
2358			return {
2359				afterSanitizeAttributes: [],
2360				afterSanitizeElements: [],
2361				afterSanitizeShadowDOM: [],
2362				beforeSanitizeAttributes: [],
2363				beforeSanitizeElements: [],
2364				beforeSanitizeShadowDOM: [],
2365				uponSanitizeAttribute: [],
2366				uponSanitizeElement: [],
2367				uponSanitizeShadowNode: []
2368			};
2369		};
2370		_resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
2371			return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
2372		};
2373		_resolveObjectOption = function _resolveObjectOption(cfg, key, makeFallback) {
2374			const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
2375			return value && typeof value === "object" ? clone(value) : makeFallback();
2376		};
2377		purify = createDOMPurify();
2378	})))();
2379}
2380//#endregion
2381export { purify as n, init_purify_es as t };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.