From 2cfad450751624f26b8c70e035313993af8506ef Mon Sep 17 00:00:00 2001 From: Per Starke Date: Sat, 8 Jun 2024 14:09:35 +0200 Subject: [PATCH] locally host nutshell + remove clickable embed icon --- _layouts/default.html | 2 +- assets/js/nutshell.js | 2282 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2283 insertions(+), 1 deletion(-) create mode 100644 assets/js/nutshell.js diff --git a/_layouts/default.html b/_layouts/default.html index 087ebe3..2eac8c8 100755 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -4,7 +4,7 @@ {% capture title %}{% if page.title %}{{ page.title }} | {% endif %}{{ site.title }}{% endcapture %} {% seo %} - + {% include page-url-resolver.html page=page %} {% if page.excerpt %} {% assign description = page.excerpt | strip_html | strip_newlines | truncate: 160 %} diff --git a/assets/js/nutshell.js b/assets/js/nutshell.js new file mode 100644 index 0000000..7c6d056 --- /dev/null +++ b/assets/js/nutshell.js @@ -0,0 +1,2282 @@ +/************************************************************************* + + +███╗░░██╗██╗░░░██╗████████╗░██████╗██╗░░██╗███████╗██╗░░░░░██╗░░░░░ +████╗░██║██║░░░██║╚══██╔══╝██╔════╝██║░░██║██╔════╝██║░░░░░██║░░░░░ +██╔██╗██║██║░░░██║░░░██║░░░╚█████╗░███████║█████╗░░██║░░░░░██║░░░░░ +██║╚████║██║░░░██║░░░██║░░░░╚═══██╗██╔══██║██╔══╝░░██║░░░░░██║░░░░░ +██║░╚███║╚██████╔╝░░░██║░░░██████╔╝██║░░██║███████╗███████╗███████╗ +╚═╝░░╚══╝░╚═════╝░░░░╚═╝░░░╚═════╝░╚═╝░░╚═╝╚══════╝╚══════╝╚══════╝ + +v1.0.7 - "Baby's First XSS Vulnerability" + +( NOTE TO SELF: When updating version, remember to edit... ) +( this js file's "Nutshell.version", include_nutshell.js ) +( and README.md what translations finished ) +( ACTUALLY MAKE A RELEASE ON GITHUB ) + +You know how in Memento, the amnesia guy tattoos reminders on his body? +That is how I document my code. The following "documentation" +is for future Nicky to remember what the heck they were doing. +If you find it helpful, that is a side effect. + +( ascii art made with https://fsymbols.com/generators/carty/ ) + + +========================= +=== DESIGN PRINCIPLES === +========================= + +Dead Simple: +Just put a " onclick="select()"/>`); + + // Step 2: Link + _p2.innerHTML = Nutshell.getLocalizedText("embedStep2") + .replace(`[LINK]`,` + `); + + // Step 3: That's all, folks! + _p3.innerHTML = Nutshell.getLocalizedText("embedStep3"); + + // (Learn More) + _p4.innerHTML = `` + + Nutshell.getLocalizedText("learnMore") + + ``; + + // Also, now that document.body exists, put it in + document.body.appendChild(_e); + + }; + + // Show Embed Modal (with what URL & linktext?) + Nutshell.showEmbedModal = (url, linkText)=>{ + + // Animate: show, then fade in. + _e.style.display = 'block'; + setTimeout(()=>{ _e.setAttribute("mode","shown"); },1); + + // Reset Step 0's Example + _p0.innerHTML = Nutshell.getLocalizedText("embedStep0") + .replace(`[EXAMPLE]`,`:${linkText}`); + Nutshell.convertLinksToExpandables(_p0); + + // Update Step 2's link URL + _e.querySelector("#nutshell-embed-modal-link").value = url; + + }; + + // Hide Embed Modal + Nutshell.closeEmbedModal = ()=>{ + // Animate: fade away, then hide + _e.setAttribute("mode","hidden"); + setTimeout(()=>{ _e.style.display='none'; },ANIM_TIME); + }; + + + ///////////////////////////////////////////////////////////////////// + // ⭐️ NUTSHELL STYLE (putting css in js, so Nutshell is *one* file) + ///////////////////////////////////////////////////////////////////// + + // The tiny Nutshell icon + Nutshell._dataURIImage = "data:image/png;base64,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"; + + Nutshell.defaultStyle = ` + + /*************************************************** + HEADERS with link / embed options + ***************************************************/ + + .nutshell-heading{ + position:relative; + } + .nutshell-heading-embed{ + + /* Position at end of heading text */ + width: 0; /* don't force newline */ + display: inline-block; + position: relative; + top:0.14em; left:0; + + /* Button, reveal on hover */ + opacity:0; + cursor: pointer; + transition: all 0.1s ease-in-out; + + } + .nutshell-heading-embed img{ + width:1em; height:1em; + min-width: 1em; + min-height: 1em; /* some deal with the devil */ + } + .nutshell-heading:hover .nutshell-heading-embed{ + left:0.25em; + opacity:0.33; + } + .nutshell-heading:hover .nutshell-heading-embed:hover{ + opacity:1; + } + + /*************************************************** + EXPANDABLE LINKS + ***************************************************/ + + .nutshell-expandable{ + + /* Boring style to fit parent */ + color: inherit; + text-decoration: none; + border-bottom: dotted 1.5px; + + /* So those balls work */ + position:relative; + + /* Animate opacity on hover */ + transition: opacity 0.1s ease-in-out; + opacity: 1; + + } + .nutshell-expandable:hover{ + color: inherit; + opacity: 0.8; + } + .nutshell-expandable .nutshell-expandable-text{ + padding-left: 0.35em; /* Give balls space */ + } + /* The balls! */ + .nutshell-ball-up, .nutshell-ball-down{ + + /* Placed to the left */ + position: absolute; + display: inline-block; + left: 1px; + + /* They're balls */ + width: 0.15em; + height: 0.15em; + background: #000; + border-radius: 1em; + + /* Animate moving up & down */ + transition: top 0.1s ease-in-out; + + } + /* Ball animation! Depends on open/closed, hover */ + .nutshell-expandable[mode=closed] .nutshell-ball-up{ top:0.4em; } + .nutshell-expandable[mode=closed] .nutshell-ball-down{ top:0.7em; } + .nutshell-expandable[mode=closed]:hover .nutshell-ball-up{ top:0.2em; } + .nutshell-expandable[mode=closed]:hover .nutshell-ball-down{ top:0.9em; } + .nutshell-expandable[mode=open] .nutshell-ball-up{ top:0.4em; } + .nutshell-expandable[mode=open] .nutshell-ball-down{ top:0.7em; } + .nutshell-expandable[mode=open]:hover .nutshell-ball-up{ top:0.55em; } + .nutshell-expandable[mode=open]:hover .nutshell-ball-down{ top:0.55em; } + + /* Followup! */ + .nutshell-followup{ + opacity:0.33; + } + + /*************************************************** + BUBBLES: + ***************************************************/ + + .nutshell-bubble{ + + /* Gon' stretch out */ + display: inline-block; + width: 100%; + + /* It's nice & speech-bubble-lookin' */ + border: 1px solid black; + /*border: 1px solid #ddd;*/ + border-radius: 20px; + + /* For the speech-bubble arrow */ + position: relative; + margin-top: 22px; + + /* For subtle move up & down */ + position: relative; + top: 0; + transition: top 0.3s linear; + + } + + /* Arrow outline */ + .nutshell-bubble-arrow{ + width: 0; + height: 0; + border-left: 20px solid transparent; + border-right: 20px solid transparent; + border-bottom: 20px solid #000; + /*border-bottom: 20px solid #ddd;*/ + position: absolute; + top: -20px; + pointer-events: none; /* don't block clicking */ + --arrow-background: #fff; /* css var */ + } + + /* Arrow white */ + .nutshell-bubble-arrow::after{ + content: ""; + width: 0; + height: 0; + border-left: 20px solid transparent; + border-right: 20px solid transparent; + border-bottom: 20px solid #fff; /* fallback */ + border-bottom: 20px solid var(--arrow-background); /* css var */ + position: absolute; + top: 1.5px; + left: -20px; + pointer-events: none; /* don't block clicking */ + } + + /* Overflow: contains the head/section/food */ + .nutshell-bubble-overflow{ + overflow: hidden; + } + .nutshell-bubble-overflow[mode=opening]{ + transition: height 0.3s ease-out; /* Snap to open */ + } + .nutshell-bubble-overflow[mode=closing]{ + transition: height 0.3s ease-in; /* Snap to close */ + } + + /* Head: Embed Button, show on hover */ + .nutshell-bubble-overflow-embed-button{ + position: absolute; + top:5px; right:10px; + width:1em; height:1em; + opacity:0; + transition: all 0.1s ease-in-out; + cursor:pointer; + } + .nutshell-bubble-overflow-embed-button img{ + width:1em; height:1em; + } + .nutshell-bubble-overflow:hover > .nutshell-bubble-overflow-embed-button{ + right: 5px; + opacity: 0.33; + } + .nutshell-bubble-overflow:hover > .nutshell-bubble-overflow-embed-button:hover{ + opacity: 1.0; + } + /* NO EMBEDDING IF IT'S A PREVIEW INSIDE EMBED MODAL */ + .nutshell-embed-modal .nutshell-bubble-overflow-embed-button{ + display:none; + } + + /* Section */ + .nutshell-bubble-overflow-section{ + padding: 0 1em; + padding-bottom: 0.5em; + overflow: hidden; /* to capture full height, including

's margins */ + } + .nutshell-bubble-overflow-section > div{ + margin: 1em 0; /* if you people forgot to put your text in

's -_- */ + } + .nutshell-bubble-overflow-section img{ + max-width:100%; /* so it fits */ + } + .nutshell-bubble-overflow-section video{ + max-width:100%; /* so it fits */ + } + /* Total hack for nice styling */ + .nutshell-bubble-overflow-section img[data-float=left]{ + float: left; + margin: 1em; + } + .nutshell-bubble-overflow-section img[data-float=right]{ + float: right; + margin: 1em; + } + .nutshell-bubble-overflow-section iframe{ + max-width:100%; /* so it fits */ + border: 1px solid rgba(0,0,0,0.2); + } + .nutshell-bubble-overflow-section .nutshell-bubble{ + /* So that recursive bubbles don't get squashed too quickly */ + width: calc(100% + 2em - 6px); /* undo section's padding, minus a gap */ + position: relative; + right: calc(1em - 2px); + } + + /* From */ + .nutshell-bubble-from{ + font-size: 0.69em; + /* line-height: 0.69em; */ + margin-bottom: -0.69em; + opacity: 0.69; + } + + /* Foot: is a close button, too. */ + .nutshell-bubble-overflow-close{ + + /* A × sign */ + font-family: inherit; + font-size: 1rem; + text-align: center; + + /* Whole-width bottom */ + position:absolute; + width:100%; + bottom:0; + border: 0; + background: none; + + /* A button that gets darker. */ + cursor:pointer; + opacity: 0.33; + transition: opacity 0.1s ease-in-out; + + } + .nutshell-bubble-overflow-close:hover{ + background: none; + opacity:1; + } + + /* Misc styling for bubbles. I am a busybody. */ + .nutshell-bubble li{ + margin-bottom: 0.5em; + } + .nutshell-bubble code{ + background: #ddd; + border-radius: 5px; + /*font-weight:100;*/ + padding: 0 5px; + } + .nutshell-bubble blockquote{ + /*background: #eee;*/ + margin-left: 0px; + margin-right: 0px; + border-left: 0.5em solid #eee; + padding: 1px 1em 1px 1.5em; + margin-top: 0; + } + + /*************************************************** + EMBED MODAL + ***************************************************/ + + .nutshell-embed-modal{ + + /* TAKE UP WHOLE SCREEN */ + position: fixed; + z-index: 99999; + top: 0; + left: 0; + width: 100%; + height: 100%; + + /* Animate by fade in */ + transition: opacity 0.3s ease-in-out; + opacity: 1; + } + .nutshell-embed-modal[mode=shown]{ opacity:1; } + .nutshell-embed-modal[mode=hidden]{ opacity:0; } + + /* Background is a big transparent black */ + #nutshell-embed-modal-bg{ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.5); + } + + /* Bubble is a big white rounded rect */ + #nutshell-embed-modal-bubble{ + + /* In the middle */ + position: absolute; + margin: auto; + top: 0; left: 0; right: 0; bottom: 0; + width: 600px; + height: 450px; + + /* Color & font */ + background: #fff; + color: #000; + border-radius: 30px; + font-size: 20px; + line-height: 1.5em; + + /* Animate by slide up */ + transition: top 0.3s ease-in-out; + } + .nutshell-embed-modal[mode=shown] #nutshell-embed-modal-bubble{ top:0; } + .nutshell-embed-modal[mode=hidden] #nutshell-embed-modal-bubble{ top:100px; } + + /* Close button */ + #nutshell-embed-modal-close{ + + /* Top right button */ + z-index: 999; + position: absolute; + top: 5px; right: 10px; + cursor: pointer; + + /* Just a times sign */ + font-size: 40px; + /*font-weight: 100;*/ + height: 40px; + + /* Anim */ + opacity: 0.25; + transition: opacity 0.1s ease-in-out; + + } + #nutshell-embed-modal-close:hover{ + opacity:1; + } + + /* Can scroll inside! */ + #nutshell-embed-modal-overflow{ + overflow-x: visible; + overflow-y: scroll; + padding: 15px 30px; + width: calc(100% - 60px); + height: calc(100% - 30px); + } + + /* The "inputs" in the modal should look code-like */ + #nutshell-embed-modal-bubble input{ + width: 100%; + font-size: 14px; + font-family: monospace; + } + + /* Learn More */ + #nutshell-embed-p4{ + font-size: 0.7em; + line-height: 0em; + text-align: center; + margin-top: 3em; + } + + /*************************************************** + CLOSE ALL NUTSHELLS + ***************************************************/ + + #nutshell-close-all{ + + /* Top-right */ + position: fixed; + top: 0; right: 0; + + /* Fades in & out */ + transition: opacity 0.9s ease-in-out; + opacity: 0; + text-align: right; + cursor: pointer; + + /* Little text */ + font-size: 0.7em; + line-height: 1.2em; + + /* Rounded corner */ + /*background: inherit;*/ + background: #fff; + padding: 0.7em; + border-radius: 0 0 0 1em; + + } + #nutshell-close-all[show=yes]{ + opacity:1; + } + #nutshell-close-all[show=no]{ + opacity:0; + } + + `; + + // I give up on hoping that CSS will be rendered + // consistently across browsers. + Nutshell.firefoxStyle = ` + /* Ball animation! Depends on open/closed, hover */ + .nutshell-expandable[mode=closed] .nutshell-ball-up{ top:0.2em; } + .nutshell-expandable[mode=closed] .nutshell-ball-down{ top:0.5em; } + .nutshell-expandable[mode=closed]:hover .nutshell-ball-up{ top:0.0em; } + .nutshell-expandable[mode=closed]:hover .nutshell-ball-down{ top:0.7em; } + .nutshell-expandable[mode=open] .nutshell-ball-up{ top:0.2em; } + .nutshell-expandable[mode=open] .nutshell-ball-down{ top:0.5em; } + .nutshell-expandable[mode=open]:hover .nutshell-ball-up{ top:0.35em; } + .nutshell-expandable[mode=open]:hover .nutshell-ball-down{ top:0.35em; } + `; + + + // Add the above styles, and any custom the user may have added! + Nutshell.addStyles = ()=>{ + + // PREPENDING styles, in reverse order. + // Prepend so that so user-made CSS can override! + let styleEl; + + // Firefox? + if(navigator.userAgent.indexOf("Firefox")>0){ + styleEl = document.createElement("style"); + styleEl.innerHTML = Nutshell.firefoxStyle; + document.head.prepend(styleEl); + } + + // Default + styleEl = document.createElement("style"); + styleEl.innerHTML = Nutshell.defaultStyle; + document.head.prepend(styleEl); + + }; + +} + + +/************************************************************************* + +OPEN SOURCE LIBRARIES I'M PUTTING DIRECTLY INTO THIS JAVASCRIPT FILE +COZ AIN'T NOBODY WANT A REPEAT OF THE LEFT-PAD FIASCO + +Included: DOMPurify, Marked + +*************************************************************************/ + +/*! @license DOMPurify 2.3.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.6/LICENSE */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,n){return(t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function r(e,o,a){return(r=n()?Reflect.construct:function(e,n,r){var o=[null];o.push.apply(o,n);var a=new(Function.bind.apply(e,o));return r&&t(a,r.prototype),a}).apply(null,arguments)}function o(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?n-1:0),o=1;o/gm),q=f(/^data-[\-\w.\u00B7-\uFFFF]/),Y=f(/^aria-[\-\w]+$/),K=f(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),V=f(/^(?:\w+script|data):/i),$=f(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),X=f(/^html$/i),Z=function(){return"undefined"==typeof window?null:window},J=function(t,n){if("object"!==e(t)||"function"!=typeof t.createPolicy)return null;var r=null,o="data-tt-policy-suffix";n.currentScript&&n.currentScript.hasAttribute(o)&&(r=n.currentScript.getAttribute(o));var a="dompurify"+(r?"#"+r:"");try{return t.createPolicy(a,{createHTML:function(e){return e}})}catch(e){return console.warn("TrustedTypes policy "+a+" could not be created."),null}};return function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Z(),r=function(e){return t(e)};if(r.version="2.3.6",r.removed=[],!n||!n.document||9!==n.document.nodeType)return r.isSupported=!1,r;var a=n.document,i=n.document,l=n.DocumentFragment,c=n.HTMLTemplateElement,u=n.Node,s=n.Element,f=n.NodeFilter,p=n.NamedNodeMap,d=void 0===p?n.NamedNodeMap||n.MozNamedAttrMap:p,h=n.HTMLFormElement,g=n.DOMParser,y=n.trustedTypes,_=s.prototype,Q=C(_,"cloneNode"),ee=C(_,"nextSibling"),te=C(_,"childNodes"),ne=C(_,"parentNode");if("function"==typeof c){var re=i.createElement("template");re.content&&re.content.ownerDocument&&(i=re.content.ownerDocument)}var oe=J(y,a),ae=oe?oe.createHTML(""):"",ie=i,le=ie.implementation,ce=ie.createNodeIterator,ue=ie.createDocumentFragment,se=ie.getElementsByTagName,me=a.importNode,fe={};try{fe=D(i).documentMode?i.documentMode:{}}catch(e){}var pe={};r.isSupported="function"==typeof ne&&le&&void 0!==le.createHTMLDocument&&9!==fe;var de,he,ge=G,ye=W,be=q,ve=Y,Te=V,Ne=$,Ee=K,Ae=null,we=O({},[].concat(o(M),o(R),o(L),o(F),o(U))),xe=null,Se=O({},[].concat(o(z),o(B),o(j),o(P))),ke=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),_e=null,Oe=null,De=!0,Ce=!0,Me=!1,Re=!1,Le=!1,Ie=!1,Fe=!1,He=!1,Ue=!1,ze=!1,Be=!0,je=!0,Pe=!1,Ge={},We=null,qe=O({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Ye=null,Ke=O({},["audio","video","img","source","image","track"]),Ve=null,$e=O({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Xe="http://www.w3.org/1998/Math/MathML",Ze="http://www.w3.org/2000/svg",Je="http://www.w3.org/1999/xhtml",Qe=Je,et=!1,tt=["application/xhtml+xml","text/html"],nt="text/html",rt=null,ot=i.createElement("form"),at=function(e){return e instanceof RegExp||e instanceof Function},it=function(t){rt&&rt===t||(t&&"object"===e(t)||(t={}),t=D(t),Ae="ALLOWED_TAGS"in t?O({},t.ALLOWED_TAGS):we,xe="ALLOWED_ATTR"in t?O({},t.ALLOWED_ATTR):Se,Ve="ADD_URI_SAFE_ATTR"in t?O(D($e),t.ADD_URI_SAFE_ATTR):$e,Ye="ADD_DATA_URI_TAGS"in t?O(D(Ke),t.ADD_DATA_URI_TAGS):Ke,We="FORBID_CONTENTS"in t?O({},t.FORBID_CONTENTS):qe,_e="FORBID_TAGS"in t?O({},t.FORBID_TAGS):{},Oe="FORBID_ATTR"in t?O({},t.FORBID_ATTR):{},Ge="USE_PROFILES"in t&&t.USE_PROFILES,De=!1!==t.ALLOW_ARIA_ATTR,Ce=!1!==t.ALLOW_DATA_ATTR,Me=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Re=t.SAFE_FOR_TEMPLATES||!1,Le=t.WHOLE_DOCUMENT||!1,He=t.RETURN_DOM||!1,Ue=t.RETURN_DOM_FRAGMENT||!1,ze=t.RETURN_TRUSTED_TYPE||!1,Fe=t.FORCE_BODY||!1,Be=!1!==t.SANITIZE_DOM,je=!1!==t.KEEP_CONTENT,Pe=t.IN_PLACE||!1,Ee=t.ALLOWED_URI_REGEXP||Ee,Qe=t.NAMESPACE||Je,t.CUSTOM_ELEMENT_HANDLING&&at(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(ke.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&at(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(ke.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(ke.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),de=de=-1===tt.indexOf(t.PARSER_MEDIA_TYPE)?nt:t.PARSER_MEDIA_TYPE,he="application/xhtml+xml"===de?function(e){return e}:N,Re&&(Ce=!1),Ue&&(He=!0),Ge&&(Ae=O({},o(U)),xe=[],!0===Ge.html&&(O(Ae,M),O(xe,z)),!0===Ge.svg&&(O(Ae,R),O(xe,B),O(xe,P)),!0===Ge.svgFilters&&(O(Ae,L),O(xe,B),O(xe,P)),!0===Ge.mathMl&&(O(Ae,F),O(xe,j),O(xe,P))),t.ADD_TAGS&&(Ae===we&&(Ae=D(Ae)),O(Ae,t.ADD_TAGS)),t.ADD_ATTR&&(xe===Se&&(xe=D(xe)),O(xe,t.ADD_ATTR)),t.ADD_URI_SAFE_ATTR&&O(Ve,t.ADD_URI_SAFE_ATTR),t.FORBID_CONTENTS&&(We===qe&&(We=D(We)),O(We,t.FORBID_CONTENTS)),je&&(Ae["#text"]=!0),Le&&O(Ae,["html","head","body"]),Ae.table&&(O(Ae,["tbody"]),delete _e.tbody),m&&m(t),rt=t)},lt=O({},["mi","mo","mn","ms","mtext"]),ct=O({},["foreignobject","desc","title","annotation-xml"]),ut=O({},R);O(ut,L),O(ut,I);var st=O({},F);O(st,H);var mt=function(e){var t=ne(e);t&&t.tagName||(t={namespaceURI:Je,tagName:"template"});var n=N(e.tagName),r=N(t.tagName);if(e.namespaceURI===Ze)return t.namespaceURI===Je?"svg"===n:t.namespaceURI===Xe?"svg"===n&&("annotation-xml"===r||lt[r]):Boolean(ut[n]);if(e.namespaceURI===Xe)return t.namespaceURI===Je?"math"===n:t.namespaceURI===Ze?"math"===n&&ct[r]:Boolean(st[n]);if(e.namespaceURI===Je){if(t.namespaceURI===Ze&&!ct[r])return!1;if(t.namespaceURI===Xe&&!lt[r])return!1;var o=O({},["title","style","font","a","script"]);return!st[n]&&(o[n]||!ut[n])}return!1},ft=function(e){T(r.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){try{e.outerHTML=ae}catch(t){e.remove()}}},pt=function(e,t){try{T(r.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){T(r.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!xe[e])if(He||Ue)try{ft(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},dt=function(e){var t,n;if(Fe)e=""+e;else{var r=E(e,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===de&&(e=''+e+"");var o=oe?oe.createHTML(e):e;if(Qe===Je)try{t=(new g).parseFromString(o,de)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(Qe,"template",null);try{t.documentElement.innerHTML=et?"":o}catch(e){}}var a=t.body||t.documentElement;return e&&n&&a.insertBefore(i.createTextNode(n),a.childNodes[0]||null),Qe===Je?se.call(t,Le?"html":"body")[0]:Le?t.documentElement:a},ht=function(e){return ce.call(e.ownerDocument||e,e,f.SHOW_ELEMENT|f.SHOW_COMMENT|f.SHOW_TEXT,null,!1)},gt=function(e){return e instanceof h&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof d)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore)},yt=function(t){return"object"===e(u)?t instanceof u:t&&"object"===e(t)&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},bt=function(e,t,n){pe[e]&&b(pe[e],(function(e){e.call(r,t,n,rt)}))},vt=function(e){var t;if(bt("beforeSanitizeElements",e,null),gt(e))return ft(e),!0;if(E(e.nodeName,/[\u0080-\uFFFF]/))return ft(e),!0;var n=he(e.nodeName);if(bt("uponSanitizeElement",e,{tagName:n,allowedTags:Ae}),!yt(e.firstElementChild)&&(!yt(e.content)||!yt(e.content.firstElementChild))&&S(/<[/\w]/g,e.innerHTML)&&S(/<[/\w]/g,e.textContent))return ft(e),!0;if("select"===n&&S(/