From ba58a694ecdcf49df9772b2888edc30778f75d0d Mon Sep 17 00:00:00 2001
From: ben-ro <ben@rott.io>
Date: Mon, 27 Jul 2026 11:28:55 +0200
Subject: [PATCH] Add data-nosnippet to link purpose text spans

Visually hidden link purpose text (e.g. "(opens in new window)") was
being picked up by search engines and appearing in result snippets,
where it reads as noise. Marking the spans with data-nosnippet keeps
the text available to assistive technology while excluding it from
Google's snippet generation.

Issue: https://www.drupal.org/i/3610931

Co-authored-by: ROXBOZ <79715224+ROXBOZ@users.noreply.github.com>
---
 index.md              | 2 +-
 js/linkpurpose.js     | 1 +
 js/linkpurpose.min.js | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/index.md b/index.md
index 109e366..89fc1e5 100644
--- a/index.md
+++ b/index.md
@@ -43,7 +43,7 @@ to this:
         <span class="link-purpose-icon link-purpose-external-icon" aria-hidden="true">
             <svg ...></svg>
         </span>
-        <span class="link-purpose-text">
+        <span class="link-purpose-text" data-nosnippet>
             (Link is external)
         </span>
     </span>
diff --git a/js/linkpurpose.js b/js/linkpurpose.js
index 3274407..6bea6aa 100644
--- a/js/linkpurpose.js
+++ b/js/linkpurpose.js
@@ -508,6 +508,7 @@ class LinkPurpose {
             if (LinkPurpose.options.hiddenTextClass) {
               iconText.classList.add(LinkPurpose.options.hiddenTextClass);
             }
+            iconText.setAttribute('data-nosnippet', '');
             iconText.setAttribute('id', `link-purpose-description-${LinkPurpose.unique}`)
             spanTarget.append(iconText);
             if (showText) {
diff --git a/js/linkpurpose.min.js b/js/linkpurpose.min.js
index 309091f..d0a5d84 100644
--- a/js/linkpurpose.min.js
+++ b/js/linkpurpose.min.js
@@ -1 +1 @@
-class LinkPurpose{constructor(s){LinkPurpose.version="1.0.9";let n=[],p=[];const t={domain:!1,watch:!(LinkPurpose.unique=0),roots:"body",shadowComponents:!1,shadowCSS:!1,hideIcon:"",noIconOnImages:"",suppressNoBreak:!1,insertIconOutsideHiddenSpan:".sr-only, .visually-hidden",ignore:"",noRunIfPresent:!1,noRunIfAbsent:!1,baseSelector:"a[href]",baseLinkClass:"link-purpose",baseIconWrapperClass:"link-purpose-icon",noBreakClass:"link-purpose-nobreak",hiddenTextClass:!1,noReferrer:!1,purposes:{newWindow:{priority:0,selector:'[target="_blank"]',message:"Link opens in new window",linkClass:"link-purpose-window",iconWrapperClass:"link-purpose-window-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M432 48H208c-17.7 0-32 14.3-32 32V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V336h16c17.7 0 32-14.3 32-32V80c0-17.7-14.3-32-32-32zM48 448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V256H48V448zM64 128H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192c0-35.3 28.7-64 64-64z"/></svg>',iconClasses:["fa-regular","fa-window-restore"],redundantStrings:/\b(window|tab)\b/i},external:{priority:10,selector:'[href^="https://"], [href^="http://"], [href^="//"]',additionalSelector:!1,newWindow:!1,message:"Link is external",linkClass:"link-purpose-external",iconWrapperClass:"link-purpose-external-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>',iconClasses:["fa-solid","fa-up-right-from-square"],redundantStrings:!1},download:{priority:20,selector:"[download]",message:"Link downloads file",linkClass:"link-purpose-download",iconWrapperClass:"link-purpose-download",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V274.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c-35.3 0-64 28.7-64 64v32c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V416c0-35.3-28.7-64-64-64H346.5l-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352H64zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/></svg>',iconClasses:["fa-solid","fa-download"],redundantStrings:/(download)/i},document:{priority:50,selector:"[href$='.pdf'], [href*='.pdf?'], [href$='.doc'], [href$='.docx'], [href*='.doc?'], [href*='.docx?'], [href$='.ppt'], [href$='.pptx'], [href*='.ppt?'], [href*='.pptx?']",message:"Links downloads document",linkClass:"link-purpose-document",iconWrapperClass:"link-purpose-document-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 384 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm56 256c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120z"/></svg>',iconClasses:["fa-regular","fa-file-lines"],redundantStrings:/\b(download|file|document|doc|docx|word|excel|xls|xlsx|powerpoint|pptx|ppt)\b/i},app:{priority:90,selector:':is([href*="://"]):not([href^="/"], [href^="https:"], [href^="http:"], [href^="file:"])',additionalSelector:!1,newWindow:!1,message:"Link opens app",linkClass:"link-purpose-app",iconWrapperClass:"link-purpose-app-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M432 64H208c-8.8 0-16 7.2-16 16V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V320h16c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16zM0 192c0-35.3 28.7-64 64-64H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192zm64 32c0 17.7 14.3 32 32 32H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H96c-17.7 0-32 14.3-32 32z"/></svg>',iconClasses:["fa-solid","fa-window-restore"],redundantStrings:!1},mail:{priority:100,selector:'[href^="mailto:"]',message:"Link opens email app",linkClass:"link-purpose-mailto",iconWrapperClass:"link-purpose-mail-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 112c-8.8 0-16 7.2-16 16v22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1V128c0-8.8-7.2-16-16-16H64zM48 212.2V384c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V212.2L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z"/></svg>',iconClasses:["fa-regular","fa-envelope"],redundantStrings:/@|mail/i},tel:{priority:100,selector:'[href^="tel:"]',message:"Link opens phone app",linkClass:"link-purpose-tel",iconWrapperClass:"link-purpose-tel-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm90.7 96.7c9.7-2.6 19.9 2.3 23.7 11.6l20 48c3.4 8.2 1 17.6-5.8 23.2L168 231.7c16.6 35.2 45.1 63.7 80.3 80.3l20.2-24.7c5.6-6.8 15-9.2 23.2-5.8l48 20c9.3 3.9 14.2 14 11.6 23.7l-12 44C336.9 378 329 384 320 384C196.3 384 96 283.7 96 160c0-9 6-16.9 14.7-19.3l44-12z"/></svg>',iconClasses:["fa-solid","fa-square-phone"],redundantStrings:!1}}};var e;let i=[];function o(){if(function(){var e=Array.from(document.querySelectorAll(LinkPurpose.options.roots+":not(.link-purpose-root)"));if(e&&(e.forEach(e=>{e.classList.add("link-purpose-root")}),i=i.concat(e)),LinkPurpose.options.shadowComponents){var o=Array.from(document.querySelectorAll(LinkPurpose.options.shadowComponents+":not(.link-purpose-root)"));if(!o)return console.warn("Link Purpose: A specified shadow host has no shadowRoot.");for(let e=0;e<o.length;e++)o[e].shadowRoot&&(o[e].classList.add("link-purpose-root"),i.push(o[e].shadowRoot),LinkPurpose.options.shadowCSS)&&LinkPurpose.attachCSS(o[e].shadowRoot)}}(),i&&(n=[],LinkPurpose.noRun=!(!LinkPurpose.options.noRunIfAbsent||null!==document.querySelector(`:is(${LinkPurpose.options.noRunIfAbsent})`)),!LinkPurpose.noRun&&LinkPurpose.options.noRunIfPresent&&(LinkPurpose.noRun=null!==document.querySelector(`:is(${LinkPurpose.options.noRunIfPresent})`)),!LinkPurpose.noRun)){const o=`:is(${LinkPurpose.options.baseSelector})`+LinkPurpose.ignore;"interactive"===document.readyState?document.onreadystatechange=()=>{LinkPurpose.run()}:i&&LinkPurpose.options.watch&&i.forEach(e=>{{if("function"!=typeof e.closest){if(e.host.matches(".link-purpose-observer"))return;e.host.classList.add("link-purpose-observer")}else{if(e.closest(".link-purpose-observer"))return;e.classList.add("link-purpose-observer")}const s=((o,s)=>{let n=null;return(...e)=>{window.clearTimeout(n),n=window.setTimeout(()=>{o.apply(null,e)},s)}})(()=>{LinkPurpose.run()},500);new MutationObserver(e=>{for(const o of e)"childList"===o.type&&o.addedNodes.length&&s()}).observe(e,{childList:!0,subtree:!0})}}),i.forEach(e=>{n=n.concat(Array.from(e.querySelectorAll(o)))})}}const d=document.createElement("span"),h=(d.classList.add("link-purpose-spacer"),d.textContent=" ",/\s*\S+\s*$/g),k=/^\s+/g,f=/\s+$/g;LinkPurpose.run=()=>{o(),p=[],n&&n.forEach(e=>{var o,s,n,t,i=[];let r=!1;for([o,s]of Object.entries(LinkPurpose.options.purposes))s.selector&&(e.matches(s.selector)||s.additionalSelector&&e.matches(s.additionalSelector))&&("newWindow"===o?r=!0:0===i.length?i.push({type:o,noReferrer:"external"===o&&LinkPurpose.options.noReferrer,suppressNoBreak:LinkPurpose.options.suppressNoBreak&&e.matches(LinkPurpose.options.suppressNoBreak)}):s.priority>LinkPurpose.options.purposes[i[0].type].priority&&(i[0]={type:o,noReferrer:"external"===o&&LinkPurpose.options.noReferrer}));r&&i.push({type:"newWindow",noReferrer:!1}),0!==i.length&&(n=!(LinkPurpose.options.hideIcon&&e.matches(LinkPurpose.options.hideIcon)),t={link:e,hits:i,showIcon:n},n&&e.parentElement&&(t.fontSize=parseInt(window.getComputedStyle(e).fontSize),t.originalWidth=e.parentElement.getBoundingClientRect().width),p.push(t))}),p&&(p.forEach(u=>{u.hits.forEach((e,n)=>{LinkPurpose.unique++;var o=!(LinkPurpose.options.purposes[e.type].redundantStrings&&0<u.link.textContent.length&&u.link.textContent.match(LinkPurpose.options.purposes[e.type].redundantStrings))&&LinkPurpose.options.purposes[e.type].message;if(0===n){let s=u.link;if(e.noReferrer&&u.link.setAttribute("rel","noreferrer"),u.showIcon){if(u.link.classList.add(LinkPurpose.options.baseLinkClass,LinkPurpose.options.purposes[e.type].linkClass),LinkPurpose.options.noIconOnImages&&u.link.classList.add("link-purpose-hide-on-image"),!e.suppressNoBreak&&"beforeend"===LinkPurpose.options.purposes[e.type].iconPosition){let o=u.link.lastChild;for(var t=[],i=[],r=[];o;)if(o.lastChild)o=o.matches(LinkPurpose.options.insertIconOutsideHiddenSpan)?(i.push(o),o.previousSibling):o.lastChild;else{if("#text"===o.nodeName&&0===o.textContent.trim().length&&o.previousSibling)t.push(o);else{if("#comment"!==o.nodeName)break;r.push(o)}o=o.previousSibling}if(o&&"#text"===o.nodeName&&0<o.textContent.length){var n=o.textContent,p=n.match(h);if(p&&p[0].length<30){u.lastWordLength=p[0].length;var a=u.lastWordLength===n.length&&!(o.previousElementSibling&&o.previousElementSibling.checkVisibility()&&/^\s/.test(p[0])),l=a&&n.match(k);let e=n.match(f);u.breakPreventer=document.createElement("span"),u.breakPreventer.textContent=p[0].trim(),u.breakPreventer.classList.add(LinkPurpose.options.noBreakClass,"link-purpose-last-word"),0<i.length&&i.forEach(e=>{u.breakPreventer.append(e)}),a?(o.textContent="",o.parentNode.append(u.breakPreventer)):(o.textContent=n.substring(0,n.length-p[0].length),o.parentNode.append(d.cloneNode(!0),u.breakPreventer)),l&&u.link.insertAdjacentText("beforebegin"," "),0<t.length&&(e=!0,t.forEach(e=>{e.textContent=""})),e&&u.link.insertAdjacentText("afterend"," "),0<r.length&&r.forEach(e=>{u.link.append(e.cloneNode(!0)),e.remove()}),s=u.breakPreventer}}}const c=document.createElement("span");c.classList.add(LinkPurpose.options.baseIconWrapperClass,LinkPurpose.options.purposes[e.type].iconWrapperClass),c.setAttribute("aria-hidden","true"),c.setAttribute("title",LinkPurpose.options.purposes[e.type].message),"html"===LinkPurpose.options.purposes[e.type].iconType?c.innerHTML=LinkPurpose.options.purposes[e.type].iconHTML:"classes"===LinkPurpose.options.purposes[e.type].iconType&&LinkPurpose.options.purposes[e.type].iconClasses.forEach(e=>{c.classList.add(e)}),s.insertAdjacentElement(LinkPurpose.options.purposes[e.type].iconPosition,c)}else u.link.classList.add(LinkPurpose.options.baseLinkClass);a=document.createElement("span");a.classList.add("link-purpose-text"),LinkPurpose.options.hiddenTextClass&&a.classList.add(LinkPurpose.options.hiddenTextClass),a.setAttribute("id","link-purpose-description-"+LinkPurpose.unique),s.append(a),o&&(u.link.hasAttribute("aria-describedby")?(u.link.setAttribute("aria-describedby",u.link.getAttribute("aria-describedby")+" link-purpose-description-"+LinkPurpose.unique),a.textContent=" "+LinkPurpose.options.purposes[e.type].message):u.link.hasAttribute("aria-description")?(u.link.setAttribute("aria-describedby","link-purpose-description-"+LinkPurpose.unique),a.textContent=u.link.getAttribute("aria-description")+", "+LinkPurpose.options.purposes[e.type].message):(u.link.setAttribute("aria-describedby","link-purpose-description-"+LinkPurpose.unique),a.textContent=" "+LinkPurpose.options.purposes[e.type].message))}else o&&((n=u.link.querySelector(".link-purpose-text")).textContent=n.textContent?` ${n.textContent}, `+LinkPurpose.options.purposes[e.type].message:""+LinkPurpose.options.purposes[e.type].message);LinkPurpose.options.purposes[e.type].newWindow&&u.link.setAttribute("target","_blank")})}),p.forEach(e=>{e.originalWidth&&e.fontSize&&e.breakPreventer&&e.lastWordLength&&8<e.lastWordLength&&e.link.getBoundingClientRect().width/e.fontSize>(e.originalWidth+e.fontSize)/e.fontSize&&e.breakPreventer.classList.remove(LinkPurpose.options.noBreakClass)}))},e=()=>{if(LinkPurpose.options={...t,...s},"object"==typeof s&&"purposes"in s)for(const o in t.purposes)o in s.purposes?(LinkPurpose.options.purposes[o]={...t.purposes[o],...s.purposes[o]},o in LinkPurpose.options.purposes&&!("priority"in LinkPurpose.options.purposes[o])&&(LinkPurpose.options.purposes[o].priority=50)):LinkPurpose.options.purposes[o]=t.purposes[o];if(LinkPurpose.ignore=LinkPurpose.options.ignore?`:not(${LinkPurpose.options.ignore}, .${LinkPurpose.options.baseLinkClass})`:`:not(.${LinkPurpose.options.baseLinkClass})`,LinkPurpose.options.purposes.external.selector&&LinkPurpose.options.domain){var e=LinkPurpose.options.domain.split(",");let s="";e.forEach((e,o)=>{e=e.trim(),0<o&&(s+=", "),0===e.indexOf("http")?s+=`[href^="${e}"]`:-1<e.indexOf("*")?s+=`[href*="${e.replaceAll("*","")}"]`:(0===e.indexOf("//")&&(e=e.substring(2)),s+=`[href^="https://${e}"], [href^="http://${e}"], [href^="//${e}"]`)}),LinkPurpose.options.purposes.external.selector=`:is(${LinkPurpose.options.purposes.external.selector}):not(${s})`}if(LinkPurpose.options.shadowComponents&&(LinkPurpose.options.shadowCSS||(e=document.querySelector('link[href*="linkpurpose.css"], link[href*="linkpurpose.min.css"]'))&&(LinkPurpose.options.shadowCSS=e.getAttribute("href")),LinkPurpose.options.shadowCSS)){let o=document.createElement("div");o.setAttribute("hidden","");e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("media","all"),e.setAttribute("href",LinkPurpose.options.shadowCSS+"?v="+LinkPurpose.version),o.append(e),LinkPurpose.attachCSS=function(e){e.appendChild(o.cloneNode(!0))}}LinkPurpose.run()},"loading"===document.readyState?document.onreadystatechange=()=>{e()}:e()}}
\ No newline at end of file
+class LinkPurpose{constructor(o){LinkPurpose.version="1.0.9";let s=[],p=[],t={domain:!1,watch:!(LinkPurpose.unique=0),roots:"body",shadowComponents:!1,shadowCSS:!1,hideIcon:"",noIconOnImages:"",suppressNoBreak:!1,insertIconOutsideHiddenSpan:".sr-only, .visually-hidden",ignore:"",noRunIfPresent:!1,noRunIfAbsent:!1,baseSelector:"a[href]",baseLinkClass:"link-purpose",baseIconWrapperClass:"link-purpose-icon",noBreakClass:"link-purpose-nobreak",hiddenTextClass:!1,noReferrer:!1,purposes:{newWindow:{priority:0,selector:'[target="_blank"]',message:"Link opens in new window",linkClass:"link-purpose-window",iconWrapperClass:"link-purpose-window-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M432 48H208c-17.7 0-32 14.3-32 32V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V336h16c17.7 0 32-14.3 32-32V80c0-17.7-14.3-32-32-32zM48 448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V256H48V448zM64 128H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192c0-35.3 28.7-64 64-64z"/></svg>',iconClasses:["fa-regular","fa-window-restore"],redundantStrings:/\b(window|tab)\b/i},external:{priority:10,selector:'[href^="https://"], [href^="http://"], [href^="//"]',additionalSelector:!1,newWindow:!1,message:"Link is external",linkClass:"link-purpose-external",iconWrapperClass:"link-purpose-external-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/></svg>',iconClasses:["fa-solid","fa-up-right-from-square"],redundantStrings:!1},download:{priority:20,selector:"[download]",message:"Link downloads file",linkClass:"link-purpose-download",iconWrapperClass:"link-purpose-download",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V274.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c-35.3 0-64 28.7-64 64v32c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V416c0-35.3-28.7-64-64-64H346.5l-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352H64zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/></svg>',iconClasses:["fa-solid","fa-download"],redundantStrings:/(download)/i},document:{priority:50,selector:"[href$='.pdf'], [href*='.pdf?'], [href$='.doc'], [href$='.docx'], [href*='.doc?'], [href*='.docx?'], [href$='.ppt'], [href$='.pptx'], [href*='.ppt?'], [href*='.pptx?']",message:"Links downloads document",linkClass:"link-purpose-document",iconWrapperClass:"link-purpose-document-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 384 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm56 256c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120z"/></svg>',iconClasses:["fa-regular","fa-file-lines"],redundantStrings:/\b(download|file|document|doc|docx|word|excel|xls|xlsx|powerpoint|pptx|ppt)\b/i},app:{priority:90,selector:':is([href*="://"]):not([href^="/"], [href^="https:"], [href^="http:"], [href^="file:"])',additionalSelector:!1,newWindow:!1,message:"Link opens app",linkClass:"link-purpose-app",iconWrapperClass:"link-purpose-app-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M432 64H208c-8.8 0-16 7.2-16 16V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V320h16c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16zM0 192c0-35.3 28.7-64 64-64H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192zm64 32c0 17.7 14.3 32 32 32H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H96c-17.7 0-32 14.3-32 32z"/></svg>',iconClasses:["fa-solid","fa-window-restore"],redundantStrings:!1},mail:{priority:100,selector:'[href^="mailto:"]',message:"Link opens email app",linkClass:"link-purpose-mailto",iconWrapperClass:"link-purpose-mail-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 512 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 112c-8.8 0-16 7.2-16 16v22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1V128c0-8.8-7.2-16-16-16H64zM48 212.2V384c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V212.2L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z"/></svg>',iconClasses:["fa-regular","fa-envelope"],redundantStrings:/@|mail/i},tel:{priority:100,selector:'[href^="tel:"]',message:"Link opens phone app",linkClass:"link-purpose-tel",iconWrapperClass:"link-purpose-tel-icon",iconType:"html",iconPosition:"beforeend",iconHTML:'<svg class="linkpurpose-default-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="Currentcolor" d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm90.7 96.7c9.7-2.6 19.9 2.3 23.7 11.6l20 48c3.4 8.2 1 17.6-5.8 23.2L168 231.7c16.6 35.2 45.1 63.7 80.3 80.3l20.2-24.7c5.6-6.8 15-9.2 23.2-5.8l48 20c9.3 3.9 14.2 14 11.6 23.7l-12 44C336.9 378 329 384 320 384C196.3 384 96 283.7 96 160c0-9 6-16.9 14.7-19.3l44-12z"/></svg>',iconClasses:["fa-solid","fa-square-phone"],redundantStrings:!1}}};var e;function n(){if((()=>{var e=Array.from(document.querySelectorAll(LinkPurpose.options.roots+":not(.link-purpose-root)"));if(e&&(e.forEach(e=>{e.classList.add("link-purpose-root")}),i=i.concat(e)),LinkPurpose.options.shadowComponents){var o=Array.from(document.querySelectorAll(LinkPurpose.options.shadowComponents+":not(.link-purpose-root)"));if(!o)return console.warn("Link Purpose: A specified shadow host has no shadowRoot.");for(let e=0;e<o.length;e++)o[e].shadowRoot&&(o[e].classList.add("link-purpose-root"),i.push(o[e].shadowRoot),LinkPurpose.options.shadowCSS)&&LinkPurpose.attachCSS(o[e].shadowRoot)}})(),i&&(s=[],LinkPurpose.noRun=!(!LinkPurpose.options.noRunIfAbsent||null!==document.querySelector(`:is(${LinkPurpose.options.noRunIfAbsent})`)),!LinkPurpose.noRun&&LinkPurpose.options.noRunIfPresent&&(LinkPurpose.noRun=null!==document.querySelector(`:is(${LinkPurpose.options.noRunIfPresent})`)),!LinkPurpose.noRun)){let o=`:is(${LinkPurpose.options.baseSelector})`+LinkPurpose.ignore;"interactive"===document.readyState?document.onreadystatechange=()=>{LinkPurpose.run()}:i&&LinkPurpose.options.watch&&i.forEach(e=>{{if("function"!=typeof e.closest){if(e.host.matches(".link-purpose-observer"))return;e.host.classList.add("link-purpose-observer")}else{if(e.closest(".link-purpose-observer"))return;e.classList.add("link-purpose-observer")}let s=((o,s)=>{let n=null;return(...e)=>{window.clearTimeout(n),n=window.setTimeout(()=>{o.apply(null,e)},s)}})(()=>{LinkPurpose.run()},500);new MutationObserver(e=>{for(var o of e)"childList"===o.type&&o.addedNodes.length&&s()}).observe(e,{childList:!0,subtree:!0})}}),i.forEach(e=>{s=s.concat(Array.from(e.querySelectorAll(o)))})}}let i=[],u=document.createElement("span"),d=(u.classList.add("link-purpose-spacer"),u.textContent=" ",/\s*\S+\s*$/g),h=/^\s+/g,k=/\s+$/g;LinkPurpose.run=()=>{n(),p=[],s&&s.forEach(e=>{var o,s,n,t,i=[];let r=!1;for([o,s]of Object.entries(LinkPurpose.options.purposes))s.selector&&(e.matches(s.selector)||s.additionalSelector&&e.matches(s.additionalSelector))&&("newWindow"===o?r=!0:0===i.length?i.push({type:o,noReferrer:"external"===o&&LinkPurpose.options.noReferrer,suppressNoBreak:LinkPurpose.options.suppressNoBreak&&e.matches(LinkPurpose.options.suppressNoBreak)}):s.priority>LinkPurpose.options.purposes[i[0].type].priority&&(i[0]={type:o,noReferrer:"external"===o&&LinkPurpose.options.noReferrer}));r&&i.push({type:"newWindow",noReferrer:!1}),0!==i.length&&(n=!(LinkPurpose.options.hideIcon&&e.matches(LinkPurpose.options.hideIcon)),t={link:e,hits:i,showIcon:n},n&&e.parentElement&&(t.fontSize=parseInt(window.getComputedStyle(e).fontSize),t.originalWidth=e.parentElement.getBoundingClientRect().width),p.push(t))}),p&&(p.forEach(c=>{c.hits.forEach((e,n)=>{LinkPurpose.unique++;var o=!(LinkPurpose.options.purposes[e.type].redundantStrings&&0<c.link.textContent.length&&c.link.textContent.match(LinkPurpose.options.purposes[e.type].redundantStrings))&&LinkPurpose.options.purposes[e.type].message;if(0===n){let s=c.link;if(e.noReferrer&&c.link.setAttribute("rel","noreferrer"),c.showIcon){if(c.link.classList.add(LinkPurpose.options.baseLinkClass,LinkPurpose.options.purposes[e.type].linkClass),LinkPurpose.options.noIconOnImages&&c.link.classList.add("link-purpose-hide-on-image"),!e.suppressNoBreak&&"beforeend"===LinkPurpose.options.purposes[e.type].iconPosition){let o=c.link.lastChild;for(var t=[],i=[],r=[];o;)if(o.lastChild)o=o.matches(LinkPurpose.options.insertIconOutsideHiddenSpan)?(i.push(o),o.previousSibling):o.lastChild;else{if("#text"===o.nodeName&&0===o.textContent.trim().length&&o.previousSibling)t.push(o);else{if("#comment"!==o.nodeName)break;r.push(o)}o=o.previousSibling}if(o&&"#text"===o.nodeName&&0<o.textContent.length){var n=o.textContent,p=n.match(d);if(p&&p[0].length<30){c.lastWordLength=p[0].length;var a=c.lastWordLength===n.length&&!(o.previousElementSibling&&o.previousElementSibling.checkVisibility()&&/^\s/.test(p[0])),l=a&&n.match(h);let e=n.match(k);c.breakPreventer=document.createElement("span"),c.breakPreventer.textContent=p[0].trim(),c.breakPreventer.classList.add(LinkPurpose.options.noBreakClass,"link-purpose-last-word"),0<i.length&&i.forEach(e=>{c.breakPreventer.append(e)}),a?(o.textContent="",o.parentNode.append(c.breakPreventer)):(o.textContent=n.substring(0,n.length-p[0].length),o.parentNode.append(u.cloneNode(!0),c.breakPreventer)),l&&c.link.insertAdjacentText("beforebegin"," "),0<t.length&&(e=!0,t.forEach(e=>{e.textContent=""})),e&&c.link.insertAdjacentText("afterend"," "),0<r.length&&r.forEach(e=>{c.link.append(e.cloneNode(!0)),e.remove()}),s=c.breakPreventer}}}let o=document.createElement("span");o.classList.add(LinkPurpose.options.baseIconWrapperClass,LinkPurpose.options.purposes[e.type].iconWrapperClass),o.setAttribute("aria-hidden","true"),o.setAttribute("title",LinkPurpose.options.purposes[e.type].message),"html"===LinkPurpose.options.purposes[e.type].iconType?o.innerHTML=LinkPurpose.options.purposes[e.type].iconHTML:"classes"===LinkPurpose.options.purposes[e.type].iconType&&LinkPurpose.options.purposes[e.type].iconClasses.forEach(e=>{o.classList.add(e)}),s.insertAdjacentElement(LinkPurpose.options.purposes[e.type].iconPosition,o)}else c.link.classList.add(LinkPurpose.options.baseLinkClass);a=document.createElement("span");a.classList.add("link-purpose-text"),LinkPurpose.options.hiddenTextClass&&a.classList.add(LinkPurpose.options.hiddenTextClass),a.setAttribute("data-nosnippet",""),a.setAttribute("id","link-purpose-description-"+LinkPurpose.unique),s.append(a),o&&(c.link.hasAttribute("aria-describedby")?(c.link.setAttribute("aria-describedby",c.link.getAttribute("aria-describedby")+" link-purpose-description-"+LinkPurpose.unique),a.textContent=" "+LinkPurpose.options.purposes[e.type].message):c.link.hasAttribute("aria-description")?(c.link.setAttribute("aria-describedby","link-purpose-description-"+LinkPurpose.unique),a.textContent=c.link.getAttribute("aria-description")+", "+LinkPurpose.options.purposes[e.type].message):(c.link.setAttribute("aria-describedby","link-purpose-description-"+LinkPurpose.unique),a.textContent=" "+LinkPurpose.options.purposes[e.type].message))}else o&&((n=c.link.querySelector(".link-purpose-text")).textContent=n.textContent?` ${n.textContent}, `+LinkPurpose.options.purposes[e.type].message:""+LinkPurpose.options.purposes[e.type].message);LinkPurpose.options.purposes[e.type].newWindow&&c.link.setAttribute("target","_blank")})}),p.forEach(e=>{e.originalWidth&&e.fontSize&&e.breakPreventer&&e.lastWordLength&&8<e.lastWordLength&&e.link.getBoundingClientRect().width/e.fontSize>(e.originalWidth+e.fontSize)/e.fontSize&&e.breakPreventer.classList.remove(LinkPurpose.options.noBreakClass)}))},e=()=>{if(LinkPurpose.options={...t,...o},"object"==typeof o&&"purposes"in o)for(var e in t.purposes)e in o.purposes?(LinkPurpose.options.purposes[e]={...t.purposes[e],...o.purposes[e]},e in LinkPurpose.options.purposes&&!("priority"in LinkPurpose.options.purposes[e])&&(LinkPurpose.options.purposes[e].priority=50)):LinkPurpose.options.purposes[e]=t.purposes[e];if(LinkPurpose.ignore=LinkPurpose.options.ignore?`:not(${LinkPurpose.options.ignore}, .${LinkPurpose.options.baseLinkClass})`:`:not(.${LinkPurpose.options.baseLinkClass})`,LinkPurpose.options.purposes.external.selector&&LinkPurpose.options.domain){var n=LinkPurpose.options.domain.split(",");let s="";n.forEach((e,o)=>{e=e.trim(),0<o&&(s+=", "),0===e.indexOf("http")?s+=`[href^="${e}"]`:-1<e.indexOf("*")?s+=`[href*="${e.replaceAll("*","")}"]`:(0===e.indexOf("//")&&(e=e.substring(2)),s+=`[href^="https://${e}"], [href^="http://${e}"], [href^="//${e}"]`)}),LinkPurpose.options.purposes.external.selector=`:is(${LinkPurpose.options.purposes.external.selector}):not(${s})`}if(LinkPurpose.options.shadowComponents&&(LinkPurpose.options.shadowCSS||(n=document.querySelector('link[href*="linkpurpose.css"], link[href*="linkpurpose.min.css"]'))&&(LinkPurpose.options.shadowCSS=n.getAttribute("href")),LinkPurpose.options.shadowCSS)){let o=document.createElement("div");o.setAttribute("hidden","");n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("media","all"),n.setAttribute("href",LinkPurpose.options.shadowCSS+"?v="+LinkPurpose.version),o.append(n),LinkPurpose.attachCSS=function(e){e.appendChild(o.cloneNode(!0))}}LinkPurpose.run()},"loading"===document.readyState?document.onreadystatechange=()=>{e()}:e()}}
\ No newline at end of file
