PageSourceSearch

http://research.periyaruniversity.ac.in/rnd-app/student-app/assets/purify.es-BKjNtD2s.js

js periyaruniversity.ac.in collected 2026-09-24 23:54:33 UTC 82,255 bytes, 2,398 lines download raw bytes

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

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.