//#region node_modules/dompurify/dist/purify.es.mjs /*! @license DOMPurify 3.4.10 | (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.10/LICENSE */ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l); else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = true, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); 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; } } var entries = Object.entries, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; var freeze = Object.freeze, seal = Object.seal, create = Object.create; var _ref = typeof Reflect !== "undefined" && Reflect, apply = _ref.apply, construct = _ref.construct; if (!freeze) freeze = function freeze(x) { return x; }; if (!seal) seal = function seal(x) { return x; }; if (!apply) apply = function apply(func, thisArg) { for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key]; return func.apply(thisArg, args); }; if (!construct) construct = function construct(Func) { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) args[_key2 - 1] = arguments[_key2]; return new Func(...args); }; var arrayForEach = unapply(Array.prototype.forEach); var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf); var arrayPop = unapply(Array.prototype.pop); var arrayPush = unapply(Array.prototype.push); var arraySplice = unapply(Array.prototype.splice); var arrayIsArray = Array.isArray; var stringToLowerCase = unapply(String.prototype.toLowerCase); var stringToString = unapply(String.prototype.toString); var stringMatch = unapply(String.prototype.match); var stringReplace = unapply(String.prototype.replace); var stringIndexOf = unapply(String.prototype.indexOf); var stringTrim = unapply(String.prototype.trim); var numberToString = unapply(Number.prototype.toString); var booleanToString = unapply(Boolean.prototype.toString); var bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString); var symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString); var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty); var objectToString = unapply(Object.prototype.toString); var regExpTest = unapply(RegExp.prototype.test); var typeErrorCreate = unconstruct(TypeError); /** * Creates a new function that calls the given function with a specified thisArg and arguments. * * @param func - The function to be wrapped and called. * @returns A new function that calls the given function with a specified thisArg and arguments. */ function unapply(func) { return function(thisArg) { if (thisArg instanceof RegExp) thisArg.lastIndex = 0; for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) args[_key3 - 1] = arguments[_key3]; return apply(func, thisArg, args); }; } /** * Creates a new function that constructs an instance of the given constructor function with the provided arguments. * * @param func - The constructor function to be wrapped and called. * @returns A new function that constructs an instance of the given constructor function with the provided arguments. */ function unconstruct(Func) { return function() { for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) args[_key4] = arguments[_key4]; return construct(Func, args); }; } /** * Add properties to a lookup table * * @param set - The set to which elements will be added. * @param array - The array containing elements to be added to the set. * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set. * @returns The modified set with added elements. */ function addToSet(set, array) { let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase; if (setPrototypeOf) setPrototypeOf(set, null); if (!arrayIsArray(array)) return set; let l = array.length; while (l--) { let element = array[l]; if (typeof element === "string") { const lcElement = transformCaseFunc(element); if (lcElement !== element) { if (!isFrozen(array)) array[l] = lcElement; element = lcElement; } } set[element] = true; } return set; } /** * Clean up an array to harden against CSPP * * @param array - The array to be cleaned. * @returns The cleaned version of the array */ function cleanArray(array) { for (let index = 0; index < array.length; index++) if (!objectHasOwnProperty(array, index)) array[index] = null; return array; } /** * Shallow clone an object * * @param object - The object to be cloned. * @returns A new object that copies the original. */ function clone(object) { const newObject = create(null); for (const _ref2 of entries(object)) { var _ref3 = _slicedToArray(_ref2, 2); const property = _ref3[0]; const value = _ref3[1]; if (objectHasOwnProperty(object, property)) if (arrayIsArray(value)) newObject[property] = cleanArray(value); else if (value && typeof value === "object" && value.constructor === Object) newObject[property] = clone(value); else newObject[property] = value; } return newObject; } /** * Convert non-node values into strings without depending on direct property access. * * @param value - The value to stringify. * @returns A string representation of the provided value. */ function stringifyValue(value) { switch (typeof value) { case "string": return value; case "number": return numberToString(value); case "boolean": return booleanToString(value); case "bigint": return bigintToString ? bigintToString(value) : "0"; case "symbol": return symbolToString ? symbolToString(value) : "Symbol()"; case "undefined": return objectToString(value); case "function": case "object": { if (value === null) return objectToString(value); const valueAsRecord = value; const valueToString = lookupGetter(valueAsRecord, "toString"); if (typeof valueToString === "function") { const stringified = valueToString(valueAsRecord); return typeof stringified === "string" ? stringified : objectToString(stringified); } return objectToString(value); } default: return objectToString(value); } } /** * This method automatically checks if the prop is function or getter and behaves accordingly. * * @param object - The object to look up the getter function in its prototype chain. * @param prop - The property name for which to find the getter function. * @returns The getter function found in the prototype chain or a fallback function. */ function lookupGetter(object, prop) { while (object !== null) { const desc = getOwnPropertyDescriptor(object, prop); if (desc) { if (desc.get) return unapply(desc.get); if (typeof desc.value === "function") return unapply(desc.value); } object = getPrototypeOf(object); } function fallbackValue() { return null; } return fallbackValue; } function isRegex(value) { try { regExpTest(value, ""); return true; } catch (_unused) { return false; } } var html$1 = freeze([ "a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "search", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr" ]); var svg$1 = freeze([ "svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "enterkeyhint", "exportparts", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "inputmode", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "part", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern" ]); var svgFilters = freeze([ "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence" ]); var svgDisallowed = freeze([ "animate", "color-profile", "cursor", "discard", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignobject", "hatch", "hatchpath", "mesh", "meshgradient", "meshpatch", "meshrow", "missing-glyph", "script", "set", "solidcolor", "unknown", "use" ]); var mathMl$1 = freeze([ "math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "mprescripts" ]); var mathMlDisallowed = freeze([ "maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none" ]); var text = freeze(["#text"]); var html = freeze([ "accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "command", "commandfor", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "exportparts", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inert", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "part", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "slot", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns" ]); var svg = freeze([ "accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "mask-type", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan" ]); var mathMl = freeze([ "accent", "accentunder", "align", "bevelled", "close", "columnalign", "columnlines", "columnspacing", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lquote", "lspace", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns" ]); var xml = freeze([ "xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink" ]); var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g); var ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g); var TMPLIT_EXPR = seal(/\${[\w\W]*/g); var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); var ARIA_ATTR = seal(/^aria-[\-\w]+$/); var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i); var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g); var DOCTYPE_NAME = seal(/^html$/i); var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); var ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g); var COMMENT_MARKUP_PROBE = seal(/<[/\w]/g); var FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i); var SELF_CLOSING_TAG = seal(/\/>/i); var NODE_TYPE = { element: 1, attribute: 2, text: 3, cdataSection: 4, entityReference: 5, entityNode: 6, processingInstruction: 7, comment: 8, document: 9, documentType: 10, documentFragment: 11, notation: 12 }; var getGlobal = function getGlobal() { return typeof window === "undefined" ? null : window; }; /** * Creates a no-op policy for internal use only. * Don't export this function outside this module! * @param trustedTypes The policy factory. * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). * @return The policy created (or null, if Trusted Types * are not supported or creating the policy failed). */ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") return null; let suffix = null; const ATTR_NAME = "data-tt-policy-suffix"; if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) suffix = purifyHostElement.getAttribute(ATTR_NAME); const policyName = "dompurify" + (suffix ? "#" + suffix : ""); try { return trustedTypes.createPolicy(policyName, { createHTML(html) { return html; }, createScriptURL(scriptUrl) { return scriptUrl; } }); } catch (_) { console.warn("TrustedTypes policy " + policyName + " could not be created."); return null; } }; var _createHooksMap = function _createHooksMap() { return { afterSanitizeAttributes: [], afterSanitizeElements: [], afterSanitizeShadowDOM: [], beforeSanitizeAttributes: [], beforeSanitizeElements: [], beforeSanitizeShadowDOM: [], uponSanitizeAttribute: [], uponSanitizeElement: [], uponSanitizeShadowNode: [] }; }; /** * Resolve a set-valued configuration option: a fresh set built from * cfg[key] when it is an own array property (seeded with a clone of * options.base when given, case-normalized via options.transform), * the fallback set otherwise. * * @param cfg the cloned, prototype-free configuration object * @param key the configuration property to read * @param fallback the set to use when the option is absent or not an array * @param options transform and optional base set to merge into * @returns the resolved set */ var _resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) { return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback; }; function createDOMPurify() { let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal(); const DOMPurify = (root) => createDOMPurify(root); DOMPurify.version = "3.4.10"; DOMPurify.removed = []; if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) { DOMPurify.isSupported = false; return DOMPurify; } let document = window.document; const originalDocument = document; const currentScript = originalDocument.currentScript; window.DocumentFragment; const HTMLTemplateElement = window.HTMLTemplateElement, Node = window.Node, Element = window.Element, NodeFilter = window.NodeFilter; window.NamedNodeMap === void 0 && (window.NamedNodeMap || window.MozNamedAttrMap); window.HTMLFormElement; const DOMParser = window.DOMParser, trustedTypes = window.trustedTypes; const ElementPrototype = Element.prototype; const cloneNode = lookupGetter(ElementPrototype, "cloneNode"); const remove = lookupGetter(ElementPrototype, "remove"); const getNextSibling = lookupGetter(ElementPrototype, "nextSibling"); const getChildNodes = lookupGetter(ElementPrototype, "childNodes"); const getParentNode = lookupGetter(ElementPrototype, "parentNode"); const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot"); const getAttributes = lookupGetter(ElementPrototype, "attributes"); const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null; const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null; if (typeof HTMLTemplateElement === "function") { const template = document.createElement("template"); if (template.content && template.content.ownerDocument) document = template.content.ownerDocument; } let trustedTypesPolicy; let emptyHTML = ""; let defaultTrustedTypesPolicy; let defaultTrustedTypesPolicyResolved = false; let IN_TRUSTED_TYPES_POLICY = 0; const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy() { 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."); }; const _createTrustedHTML = function _createTrustedHTML(html) { _assertNotInTrustedTypesPolicy(); IN_TRUSTED_TYPES_POLICY++; try { return trustedTypesPolicy.createHTML(html); } finally { IN_TRUSTED_TYPES_POLICY--; } }; const _createTrustedScriptURL = function _createTrustedScriptURL(scriptUrl) { _assertNotInTrustedTypesPolicy(); IN_TRUSTED_TYPES_POLICY++; try { return trustedTypesPolicy.createScriptURL(scriptUrl); } finally { IN_TRUSTED_TYPES_POLICY--; } }; const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy() { if (!defaultTrustedTypesPolicyResolved) { defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); defaultTrustedTypesPolicyResolved = true; } return defaultTrustedTypesPolicy; }; const _document = document, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName; const importNode = originalDocument.importNode; let hooks = _createHooksMap(); /** * Expose whether this browser supports running the full DOMPurify. */ DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0; 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; let IS_ALLOWED_URI$1 = IS_ALLOWED_URI; /** * We consider the elements and attributes below to be safe. Ideally * don't add any new ones but feel free to remove unwanted ones. */ let ALLOWED_TAGS = null; const DEFAULT_ALLOWED_TAGS = addToSet({}, [ ...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text ]); let ALLOWED_ATTR = null; const DEFAULT_ALLOWED_ATTR = addToSet({}, [ ...html, ...svg, ...mathMl, ...xml ]); let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, { tagNameCheck: { writable: true, configurable: false, enumerable: true, value: null }, attributeNameCheck: { writable: true, configurable: false, enumerable: true, value: null }, allowCustomizedBuiltInElements: { writable: true, configurable: false, enumerable: true, value: false } })); let FORBID_TAGS = null; let FORBID_ATTR = null; const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, { tagCheck: { writable: true, configurable: false, enumerable: true, value: null }, attributeCheck: { writable: true, configurable: false, enumerable: true, value: null } })); let ALLOW_ARIA_ATTR = true; let ALLOW_DATA_ATTR = true; let ALLOW_UNKNOWN_PROTOCOLS = false; let ALLOW_SELF_CLOSE_IN_ATTR = true; let SAFE_FOR_TEMPLATES = false; let SAFE_FOR_XML = true; let WHOLE_DOCUMENT = false; let SET_CONFIG = false; let FORCE_BODY = false; let RETURN_DOM = false; let RETURN_DOM_FRAGMENT = false; let RETURN_TRUSTED_TYPE = false; let SANITIZE_DOM = true; let SANITIZE_NAMED_PROPS = false; const SANITIZE_NAMED_PROPS_PREFIX = "user-content-"; let KEEP_CONTENT = true; let IN_PLACE = false; let USE_PROFILES = {}; let FORBID_CONTENTS = null; const DEFAULT_FORBID_CONTENTS = addToSet({}, [ "annotation-xml", "audio", "colgroup", "desc", "foreignobject", "head", "iframe", "math", "mi", "mn", "mo", "ms", "mtext", "noembed", "noframes", "noscript", "plaintext", "script", "selectedcontent", "style", "svg", "template", "thead", "title", "video", "xmp" ]); let DATA_URI_TAGS = null; const DEFAULT_DATA_URI_TAGS = addToSet({}, [ "audio", "video", "img", "source", "image", "track" ]); let URI_SAFE_ATTRIBUTES = null; const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [ "alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns" ]); const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML"; const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; let NAMESPACE = HTML_NAMESPACE; let IS_EMPTY_INPUT = false; let ALLOWED_NAMESPACES = null; const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [ MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE ], stringToString); const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze([ "mi", "mo", "mn", "ms", "mtext" ]); let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS); const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]); let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS); const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [ "title", "style", "font", "a", "script" ]); let PARSER_MEDIA_TYPE = null; const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"]; const DEFAULT_PARSER_MEDIA_TYPE = "text/html"; let transformCaseFunc = null; let CONFIG = null; const formElement = document.createElement("form"); const isRegexOrFunction = function isRegexOrFunction(testValue) { return testValue instanceof RegExp || testValue instanceof Function; }; /** * _parseConfig * * @param cfg optional config literal */ const _parseConfig = function _parseConfig() { let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; if (CONFIG && CONFIG === cfg) return; if (!cfg || typeof cfg !== "object") cfg = {}; cfg = clone(cfg); PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE; transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase; ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, { transform: transformCaseFunc }); ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, { transform: transformCaseFunc }); ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, { transform: stringToString }); URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, { transform: transformCaseFunc, base: DEFAULT_URI_SAFE_ATTRIBUTES }); DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, { transform: transformCaseFunc, base: DEFAULT_DATA_URI_TAGS }); FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, { transform: transformCaseFunc }); FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), { transform: transformCaseFunc }); FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), { transform: transformCaseFunc }); USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false; ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; RETURN_DOM = cfg.RETURN_DOM || false; RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; FORCE_BODY = cfg.FORCE_BODY || false; SANITIZE_DOM = cfg.SANITIZE_DOM !== false; SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; KEEP_CONTENT = cfg.KEEP_CONTENT !== false; IN_PLACE = cfg.IN_PLACE || false; IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI; NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE; MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS); HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS); const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null); CUSTOM_ELEMENT_HANDLING = create(null); if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck; if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements; seal(CUSTOM_ELEMENT_HANDLING); if (SAFE_FOR_TEMPLATES) ALLOW_DATA_ATTR = false; if (RETURN_DOM_FRAGMENT) RETURN_DOM = true; if (USE_PROFILES) { ALLOWED_TAGS = addToSet({}, text); ALLOWED_ATTR = create(null); if (USE_PROFILES.html === true) { addToSet(ALLOWED_TAGS, html$1); addToSet(ALLOWED_ATTR, html); } if (USE_PROFILES.svg === true) { addToSet(ALLOWED_TAGS, svg$1); addToSet(ALLOWED_ATTR, svg); addToSet(ALLOWED_ATTR, xml); } if (USE_PROFILES.svgFilters === true) { addToSet(ALLOWED_TAGS, svgFilters); addToSet(ALLOWED_ATTR, svg); addToSet(ALLOWED_ATTR, xml); } if (USE_PROFILES.mathMl === true) { addToSet(ALLOWED_TAGS, mathMl$1); addToSet(ALLOWED_ATTR, mathMl); addToSet(ALLOWED_ATTR, xml); } } EXTRA_ELEMENT_HANDLING.tagCheck = null; EXTRA_ELEMENT_HANDLING.attributeCheck = null; if (objectHasOwnProperty(cfg, "ADD_TAGS")) { if (typeof cfg.ADD_TAGS === "function") EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS; else if (arrayIsArray(cfg.ADD_TAGS)) { if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) ALLOWED_TAGS = clone(ALLOWED_TAGS); addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); } } if (objectHasOwnProperty(cfg, "ADD_ATTR")) { if (typeof cfg.ADD_ATTR === "function") EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR; else if (arrayIsArray(cfg.ADD_ATTR)) { if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) ALLOWED_ATTR = clone(ALLOWED_ATTR); addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); } } if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) { if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS); addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); } if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) { if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS); addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc); } if (KEEP_CONTENT) ALLOWED_TAGS["#text"] = true; if (WHOLE_DOCUMENT) addToSet(ALLOWED_TAGS, [ "html", "head", "body" ]); if (ALLOWED_TAGS.table) { addToSet(ALLOWED_TAGS, ["tbody"]); delete FORBID_TAGS.tbody; } if (cfg.TRUSTED_TYPES_POLICY) { if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook."); if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook."); const previousTrustedTypesPolicy = trustedTypesPolicy; trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; try { emptyHTML = _createTrustedHTML(""); } catch (error) { trustedTypesPolicy = previousTrustedTypesPolicy; throw error; } } else if (cfg.TRUSTED_TYPES_POLICY === null) { trustedTypesPolicy = void 0; emptyHTML = ""; } else { if (trustedTypesPolicy === void 0) trustedTypesPolicy = _getDefaultTrustedTypesPolicy(); if (trustedTypesPolicy && typeof emptyHTML === "string") emptyHTML = _createTrustedHTML(""); } if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) ALLOWED_TAGS = clone(ALLOWED_TAGS); if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) ALLOWED_ATTR = clone(ALLOWED_ATTR); if (freeze) freeze(cfg); CONFIG = cfg; }; const ALL_SVG_TAGS = addToSet({}, [ ...svg$1, ...svgFilters, ...svgDisallowed ]); const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]); /** * Namespace rules for an element in the SVG namespace. * * @param tagName the element's lowercase tag name * @param parent the (possibly simulated) parent node * @param parentTagName the parent's lowercase tag name * @returns true if a spec-compliant parser could produce this element */ const _checkSvgNamespace = function _checkSvgNamespace(tagName, parent, parentTagName) { if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "svg"; if (parent.namespaceURI === MATHML_NAMESPACE) return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); return Boolean(ALL_SVG_TAGS[tagName]); }; /** * Namespace rules for an element in the MathML namespace. * * @param tagName the element's lowercase tag name * @param parent the (possibly simulated) parent node * @param parentTagName the parent's lowercase tag name * @returns true if a spec-compliant parser could produce this element */ const _checkMathMlNamespace = function _checkMathMlNamespace(tagName, parent, parentTagName) { if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "math"; if (parent.namespaceURI === SVG_NAMESPACE) return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName]; return Boolean(ALL_MATHML_TAGS[tagName]); }; /** * Namespace rules for an element in the HTML namespace. * * @param tagName the element's lowercase tag name * @param parent the (possibly simulated) parent node * @param parentTagName the parent's lowercase tag name * @returns true if a spec-compliant parser could produce this element */ const _checkHtmlNamespace = function _checkHtmlNamespace(tagName, parent, parentTagName) { if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) return false; if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) return false; return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); }; /** * @param element a DOM element whose namespace is being checked * @returns Return false if the element has a * namespace that a spec-compliant parser would never * return. Return true otherwise. */ const _checkValidNamespace = function _checkValidNamespace(element) { let parent = getParentNode(element); if (!parent || !parent.tagName) parent = { namespaceURI: NAMESPACE, tagName: "template" }; const tagName = stringToLowerCase(element.tagName); const parentTagName = stringToLowerCase(parent.tagName); if (!ALLOWED_NAMESPACES[element.namespaceURI]) return false; if (element.namespaceURI === SVG_NAMESPACE) return _checkSvgNamespace(tagName, parent, parentTagName); if (element.namespaceURI === MATHML_NAMESPACE) return _checkMathMlNamespace(tagName, parent, parentTagName); if (element.namespaceURI === HTML_NAMESPACE) return _checkHtmlNamespace(tagName, parent, parentTagName); if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) return true; return false; }; /** * _forceRemove * * @param node a DOM node */ const _forceRemove = function _forceRemove(node) { arrayPush(DOMPurify.removed, { element: node }); try { getParentNode(node).removeChild(node); } catch (_) { remove(node); 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"); } }; /** * _neutralizeRoot * * Fail-closed teardown of an in-place root after the sanitize walk aborts * (campaign-3 F2). An internal throw mid-walk — e.g. a page-registered * custom element's reaction detaches a node so `_forceRemove`'s deliberate * parentless guard throws, or any other re-entrant engine mutation — would * otherwise leave the caller's *live* tree half-sanitized, with everything * after the abort point still carrying its handlers. There is no safe way * to resume the walk (the tree mutated under us), so we strip the root bare: * remove every child and every attribute, then let the caller's catch see * the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes` * getters; the root was already clobber-pre-flighted at the IN_PLACE entry). * * @param root the in-place root to empty */ const _neutralizeRoot = function _neutralizeRoot(root) { const childNodes = getChildNodes(root); if (childNodes) { const snapshot = []; arrayForEach(childNodes, (child) => { arrayPush(snapshot, child); }); arrayForEach(snapshot, (child) => { try { remove(child); } catch (_) {} }); } const attributes = getAttributes(root); if (attributes) for (let i = attributes.length - 1; i >= 0; --i) { const attribute = attributes[i]; const name = attribute && attribute.name; if (typeof name === "string") try { root.removeAttribute(name); } catch (_) {} } }; /** * _removeAttribute * * @param name an Attribute name * @param element a DOM node */ const _removeAttribute = function _removeAttribute(name, element) { try { arrayPush(DOMPurify.removed, { attribute: element.getAttributeNode(name), from: element }); } catch (_) { arrayPush(DOMPurify.removed, { attribute: null, from: element }); } element.removeAttribute(name); if (name === "is") if (RETURN_DOM || RETURN_DOM_FRAGMENT) try { _forceRemove(element); } catch (_) {} else try { element.setAttribute(name, ""); } catch (_) {} }; /** * _stripDisallowedAttributes * * Removes every attribute the active configuration does not allow from a * single element, using the same allowlist as the main attribute pass (so * `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to * neutralise nodes that are being discarded from an in-place tree. * * @param element the element to strip */ const _stripDisallowedAttributes = function _stripDisallowedAttributes(element) { const attributes = getAttributes(element); if (!attributes) return; for (let i = attributes.length - 1; i >= 0; --i) { const attribute = attributes[i]; const name = attribute && attribute.name; if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue; try { element.removeAttribute(name); } catch (_) {} } }; /** * _neutralizeSubtree * * Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT * move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary, * namespace, comment, processing-instruction and KEEP_CONTENT:false removals * all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path * those dropped nodes are detached from the caller's LIVE tree but a * handler-bearing original among them (an ``/`