@phun-ky/speccer 11.2.8 → 11.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -677,7 +677,7 @@ $ npm test
677
677
 
678
678
  ## Used by
679
679
 
680
- ![](./public/used-by-if.png)
680
+ ![if logo](./public/used-by-if.png)
681
681
 
682
682
  ## Contributing
683
683
 
@@ -2,9 +2,9 @@
2
2
  * @phun-ky/speccer
3
3
  * A script to annotate, show spacing specs and to display typography information in documentation/website on HTML elements
4
4
  * @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
5
- * @version 11.2.8
5
+ * @version 11.2.10
6
6
  * @license
7
- * Copyright (c) 2018 Alexander Vassbotn Røyne-Helgesen
7
+ * Copyright (c) 2018-2025 Alexander Vassbotn Røyne-Helgesen
8
8
  *
9
9
  * Permission is hereby granted, free of charge, to any person obtaining a copy
10
10
  * of this software and associated documentation files (the "Software"), to deal
@@ -25,4 +25,3 @@
25
25
  * SOFTWARE.
26
26
  */
27
27
  const t=t=>"string"==typeof t,e=e=>!t(e),n=t=>"number"==typeof t,o=t=>!n(t),i=t=>void 0===t,r=(t,e,n="noop")=>{if(!t)return;if(!e||e&&!e.length)return;const o=e.trim().split(" ").filter((t=>t!==n)).filter((t=>""!==t)).map((t=>t.trim()));t.classList.add(...o)},s=(t,n)=>t?!n&&e(t)?Object.keys(t).filter((e=>t[e])).join(" ").trim():`${t.trim()} ${n?Object.keys(n).filter((t=>n[t])).join(" "):""}`.trim():"",a=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],c="data-speccer",p="spacing",l="measure",d="typography",h="mark",u="grid",f="pin-area";var g,m,y,w,b,x,$;!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(g||(g={})),function(t){t.Pin="pin",t.Parent="parent",t.Text="text",t.Enclose="enclose",t.Subtle="subtle",t.Bracket="bracket",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(m||(m={})),function(t){t.Measure="measure",t.Slim="slim",t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(y||(y={})),function(t){t.Typography="typography",t.Syntax="syntax",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(w||(w={})),function(t){t.Spacing="spacing"}(b||(b={})),function(t){t.Mark="mark"}(x||(x={})),function(t){t.Grid="grid"}($||($={}));const E=t=>t.split(" "),A=t=>{if(null===t)return!1;return E(t).includes(m.Bracket)},S=t=>{if(null===t)return!1;return E(t).includes(m.Enclose)},C=t=>{if(null===t)return!1;return E(t).includes(m.Subtle)},k=t=>{if(null===t)return!1;return E(t).includes(m.Parent)},v=t=>{if(null===t)return!1;return E(t).includes(m.Text)},P=t=>{if(null===t)return!1;return E(t).includes(y.Height)},L=t=>{if(null===t)return!1;return E(t).includes(y.Slim)},B=t=>{if(null===t)return!1;return E(t).includes(y.Width)},R=t=>{if(null===t)return!1;const e=E(t);return(k(t)&&!S(t)&&!A(t)||v(t)||e.includes(m.SVG))&&!T(t)},T=t=>{if(null===t)return!1;const e=E(t);return e.includes(m.Curly)&&e.includes(m.Bracket)},N=t=>!!t&&t.split(" ").includes(w.Syntax),q=(e,n)=>(t=>null!==t&&t.split(" ").includes(m.Pin))(e)?"pin":((e,n)=>null!==e&&e.split(" ").includes($.Grid)&&t(n.display)&&("grid"===n.display||(n.display||"").includes("grid")))(e,n)?"grid":(t=>null!==t&&t.split(" ").includes(x.Mark))(e)?"mark":(t=>null!==t&&t.split(" ").includes(y.Measure))(e)?"measure":(t=>null!==t&&t.split(" ").includes(b.Spacing))(e)?"spacing":(t=>null!==t&&t.split(" ").includes(w.Typography))(e)?"typography":"pin",H=t=>(t=>null!==t&&E(t).includes(m.Left))(t)?"left":(t=>null!==t&&E(t).includes(m.Right))(t)?"right":(t=>null!==t&&E(t).includes(m.Bottom))(t)?"bottom":"top",I=(t,e,n)=>{const o=q(t,e),i={slug:(r=t,r.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").trim().toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/\s+/g," ").replace(/(?:^\w|[A-Z]|\b\w)/g,((t,e)=>0===e?t.toLowerCase():t.toUpperCase())).replace(/\s+/g,"")),position:H(t),type:o};var r;if("pin"===o&&(i.pin={bracket:A(t),enclose:S(t),subtle:C(t),parent:k(t),text:v(t),useSVGLine:R(t),useCurlyBrackets:T(t)}),"measure"===o&&(i.measure={slim:L(t),height:P(t),width:B(t)}),"typography"===o&&(i.typography={useSyntaxHighlighting:N(t)}),"grid"===o){const e=(t=>t?.includes("columns")?"columns":t?.includes("rows")?"rows":"both")(t);i.grid={toggle:e,both:"both"===e,rows:"rows"===e,columns:"columns"===e}}if("spacing"===o){const e=(t=>t?.includes("margin")?"margin":t?.includes("padding")?"padding":"both")(t);i.spacing={both:"both"===e,margin:"margin"===e,padding:"padding"===e,bound:t.includes("bound")}}return{...i,...n}},M=()=>"_"+Math.random().toString(36).substring(2,11),O=t=>!t.checkVisibility({opacityProperty:!0,checkVisibilityCSS:!0}),V=()=>new Promise(requestAnimationFrame),z=async(t,e,n)=>{await V();return getComputedStyle(t)[e]===n},G=async(t,e,n)=>{if(!t.parentElement)return null;return await z(t.parentElement,e,n)?t.parentElement:await G(t.parentElement,e,n)},j=(t,e,n)=>t-e.width/2+n.width/2,W=(t,e,n)=>t-e.height/2+n.height/2,D=async t=>{await V();let e=t.getBoundingClientRect(),n=e.top+window.scrollY;const o=e.left+window.scrollX,i=await(async t=>await G(t,"position","sticky"))(t);if(await(async t=>await z(t,"position","sticky"))(t)){const o=t.style.position;await V(),t.style.position="relative",await V(),e=t.getBoundingClientRect(),n=e.top,await V(),t.style.position=o}else if(i){const o=i.style.position;await V(),i.style.position="relative",await V(),e=t.getBoundingClientRect(),n=e.top,await V(),i.style.position=o}return{height:e.height,width:e.width,top:n,left:o}},F=async(t,e)=>{await V();const n=t.getBoundingClientRect(),o=await D(e),i=await(async(t,e)=>{await V();const n=t.getBoundingClientRect();await V();const o=e.getBoundingClientRect(),i=o.top+window.scrollY,r=o.left+window.scrollX;return{height:o.height,width:o.width,top:W(i,n,o),left:j(r,n,o)}})(t,e),r=o.height,s=o.width,a=n.height,c=n.width;return{absolute:()=>({top:o.top,left:o.left,height:r,width:s}),toTop:({center:t=!1,sourceHeight:e=a,modifier:n=0}={})=>({top:o.top+e+n,left:t?i.left:o.left,height:r,width:s}),fromTop:({center:t=!1,sourceHeight:e=a,modifier:n=0}={})=>({top:o.top-e-n,left:t?i.left:o.left,height:r,width:s}),toBottom:({center:t=!1,sourceHeight:e=a,targetHeight:n=r,modifier:c=0}={})=>({top:o.top+n-(e+c),left:t?i.left:o.left,height:r,width:s}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:n=0}={})=>({top:o.top+e+n,left:t?i.left:o.left,height:r,width:s}),toLeft:({center:t=!1,sourceWidth:e=c,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left+e+n,height:r,width:s}),fromLeft:({center:t=!1,sourceWidth:e=c,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left-e-n,height:r,width:s}),toRight:({center:t=!1,sourceWidth:e=c,targetWidth:n=s,modifier:a=0}={})=>({top:t?i.top:o.top,left:o.left+n-(e+a),height:r,width:s}),fromRight:({center:t=!1,targetWidth:e=s,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left+e+n,height:r,width:s})}},_=async(e,o)=>{var i;!e||!o||t(o)||n(o)||(i=o,"boolean"==typeof i)||Array.isArray(o)&&!o.length||!Object.keys(o).length&&o.constructor===Object||(await V(),Array.isArray(o)&&(o=o.reduce(((t,e)=>(t[e.key]=e.value,t)),{})),Object.assign(e.style,o))},X=async t=>(await V(),getComputedStyle(t,null)),Y=async(t,e,n)=>{await V();const{grid:o}=n;if(!o)return;const{toggle:i}=o,{height:s,width:a}=t.getBoundingClientRect(),{top:c,left:p}=await D(t),{gridTemplateColumns:l,gridTemplateRows:d,padding:h}=e,u=`speccer-${n.slug}-${t.getAttribute("id")||M()}`;if(t.setAttribute("data-speccer-element-id",u),"columns"===i||"both"===i){const t=parseInt(e.columnGap||"0"),n=document.createElement("div");document.documentElement.style.setProperty("--ph-speccer-grid-gap-original",`${t}px`),document.documentElement.style.setProperty("--ph-speccer-grid-gap",`${t<24?24:t}px`),t<24&&n.classList.add("speccer-small-grid"),n.setAttribute("data-speccer-id",u),r(n,"ph-speccer speccer speccer-grid-container"),_(n,{height:`${s+64}px`,width:`${a}px`,left:`${p}px`,top:c-32+"px",padding:h,gridTemplateColumns:l});const o=l?.split(" ").length||0;for(let t=0;t<o;t++){const t=document.createElement("div");r(t,"ph-speccer speccer speccer-grid-item"),n.appendChild(t)}document.body.appendChild(n)}if("rows"===i||"both"===i){const t=parseInt(e.rowGap||"0"),n=document.createElement("div");document.documentElement.style.setProperty("--ph-speccer-grid-row-gap-original",`${t}px`),document.documentElement.style.setProperty("--ph-speccer-grid-row-gap",`${t<24?24:t}px`),t<24&&n.classList.add("speccer-small-grid"),n.setAttribute("data-speccer-id",u),n.classList.add("ph-speccer"),n.classList.add("speccer"),n.classList.add("speccer-grid-row-container"),r(n,"ph-speccer speccer speccer-grid-row-container"),_(n,{width:`${a+64}px`,height:`${s}px`,top:`${c}px`,left:p-32+"px",padding:h,gridTemplateRows:d});const o=d?.split(" ").length||0;for(let t=0;t<o;t++){const t=document.createElement("div");r(t,"ph-speccer speccer speccer-grid-row-item"),n.appendChild(t)}document.body.appendChild(n)}},K=async(t,e)=>{if(!t)return;if(O(t))return;const n=t.getAttribute(c)||"",o=await X(t),i=I(n,o,e);"grid"===i.type&&i.grid&&(await V(),await Y(t,o,i))},U=(t,e="span")=>{const n=document.createElement(e);return n.setAttribute("id",t),r(n,"ph-speccer speccer mark"),n},Z=async t=>{if(!t)return;if(O(t))return;const e=t.getAttribute(c)||"";await V();const n=I(e,getComputedStyle(t));if("mark"!==n.type)return;const o=`speccer-${n.slug}-${t.getAttribute("id")||M()}`;t.setAttribute("data-speccer-element-id",o);const i=U(o);i.setAttribute("data-speccer-id",o),document.body.appendChild(i);const r=await F(i,t),{left:s,top:a,height:p,width:l}=r.absolute(),d={left:`${s}px`,top:`${a}px`,height:`${p}px`,width:`${l}px`};await _(i,d)},J=(t="",e,n,o="span")=>{const i=document.createElement(o);i.setAttribute("title",`${t}px`),i.setAttribute("id",n),i.setAttribute("data-speccer-id",n),i.setAttribute("data-measure",`${parseInt(String(t),10)}px`);const{measure:a,position:c}=e,p=s("ph-speccer speccer measure",{height:a?.height||!1,width:a?.width||!1,slim:a?.slim||!1,[c]:!0});return r(i,p),i},Q=async(t,e)=>{if(!t)return;if(O(t))return;const n=t.getAttribute("data-speccer")||"";await V();const o=I(n,getComputedStyle(t),e);if("measure"!==o.type||!o.measure)return;const{measure:i,position:r}=o;await V();const s=t.getBoundingClientRect(),a=i.slim?0:48,c=i.slim?0:96,p=`speccer-${o.slug}-${t.getAttribute("id")||M()}`;if(t.setAttribute("data-speccer-element-id",p),i.width)if(r===y.Bottom){const e=J(s.width,o,p);document.body.appendChild(e);const n=await F(e,t);if(i.slim){const{left:t,top:o,width:i}=n.fromBottom({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`})}else{const{left:t,top:o,width:i,height:r}=n.absolute({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`,height:`${r+a}px`})}}else{const e=J(s.width,o,p);document.body.appendChild(e);const n=await F(e,t);if(i.slim){const{left:t,top:o,width:i}=n.fromTop({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`})}else{const{left:t,top:o,width:i,height:r}=n.absolute({center:!1});await _(e,{left:`${t}px`,top:o-a+"px",width:`${i}px`,height:`${r+a}px`})}}else if(i.height)if(r===y.Right){const e=J(s.height,o,p);document.body.appendChild(e);const n=await F(e,t);if(i.slim){const{left:t,top:o,height:i}=n.fromRight({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`})}else{const{left:t,top:o,height:i,width:r}=n.absolute({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`,width:`${r+c}px`})}}else{const e=J(s.height,o,p);document.body.appendChild(e);const n=await F(e,t);if(i.slim){const{left:t,top:o,height:i}=n.fromLeft({center:!1});await _(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`})}else{const{left:t,top:o,height:i,width:r}=n.absolute({center:!1});await _(e,{left:t-c+"px",top:`${o}px`,height:`${i}px`,width:`${r+c}px`})}}},tt=(t="",e,n="",o="span")=>{const i=document.createElement(o),a={},{position:c,pin:p={}}=e,{useSVGLine:l,useCurlyBrackets:d,text:h,parent:u,bracket:f,enclose:g,subtle:m}=p;a.text=h,a.parent=u,a.bracket=f,a.enclose=g,a.subtle=m,a.svg=l,a.curly=d,a[c]=!0,!u||f||d||m||(a.svg=!0),!f&&!g||f&&d?i.innerHTML=t:(f||g)&&i.setAttribute("data-pin-counter",t);const y=s("ph-speccer speccer pin",a);return r(i,y),i.setAttribute("id",n),i.setAttribute("data-speccer-id",n),i},et=()=>{const{body:t,documentElement:e}=document;return Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight)},nt=t=>t.top,ot=t=>t.left+t.width,it=t=>t.top+t.height,rt=t=>t.left,st=t=>t.left+t.width/2,at=t=>t.top+t.height/2,ct={center:t=>({x:st(t),y:at(t)}),top:t=>({x:st(t),y:nt(t)}),right:t=>({x:ot(t),y:at(t)}),bottom:t=>({x:st(t),y:it(t)}),left:t=>({x:rt(t),y:at(t)}),"right-top":t=>({x:ot(t),y:nt(t)}),"right-bottom":t=>({x:ot(t),y:it(t)}),"left-top":t=>({x:rt(t),y:nt(t)}),"left-bottom":t=>({x:rt(t),y:it(t)}),"top-left":t=>({x:rt(t),y:nt(t)}),"top-right":t=>({x:ot(t),y:nt(t)}),"bottom-left":t=>({x:rt(t),y:it(t)}),"bottom-right":t=>({x:ot(t),y:it(t)}),"top-center":t=>({x:st(t),y:nt(t)}),"right-center":t=>({x:ot(t),y:at(t)}),"bottom-center":t=>({x:st(t),y:it(t)}),"left-center":t=>({x:rt(t),y:at(t)})},pt=async(t,n="center")=>{if(!n)throw Error("No position given");if(e(n))throw Error("The position given is not the required type: pos: "+typeof n);const o=["center","left","right","top","bottom","right-top","right-bottom","left-top","left-bottom","top-left","top-right","bottom-left","bottom-right","top-center","right-center","bottom-center","left-center"];if(!o.includes(n))throw Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await V();const i=t.getBoundingClientRect();return ct[n](i)};class lt{#t;el;circle;radius;options;constructor(t,e,n){this.#e(t,e,n)}#e(t,e,n){if(!t||!e||!n)throw Error("Missing inputs el or radius or options");if(!document.body.contains(t))throw Error("el is not in the DOM");if(this.el=t,this.radius=e,this.options=n,this.#t=document.getElementById("ph-speccer-svg"),!this.#t)throw Error("Missing required SVG element to draw circles. Please see the documentation");const o=et();_(this.#t,{height:`${o}px`}),this.draw()}async draw(){const t=`ph_draw-circle-${M()}`;this.circle=document.createElementNS("http://www.w3.org/2000/svg","circle");const e=this.el.getAttribute("id")||M();if(this.el.setAttribute("id",e),this.circle.setAttribute("id",t),this.circle.setAttribute("data-el",e),this.circle.classList.add("ph-speccer"),this.circle.classList.add("speccer"),this.circle.classList.add("circle"),!this.#t)throw Error("No parentNode found for circle");this.#t.appendChild(this.circle);const{x:n,y:o}=await pt(this.el,this.options.position);this.circle.setAttribute("r",this.radius+""),this.circle.setAttribute("cx",Math.round(n)+""),this.circle.setAttribute("cy",Math.round(o+document.documentElement.scrollTop)+""),this.circle.setAttribute("fill","currentColor")}}window.DrawCircle=lt;const dt=async(t,e,n="center",o="center")=>{if(!t||!e)throw Error("No element given");const{x:i,y:r}=await pt(t,n),{x:s,y:a}=await pt(e,o);return{x1:i,y1:r,x2:s,y2:a}},ht=(t,e)=>{const{x1:n,x2:o,y1:i,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:c}=e,p={x:n,y:i},l={x:o,y:r};return s?a?"west"===c?{firstPoint:p,firstControl:{x:n-32,y:i-8},lastPoint:l,lastControl:{x:o+32,y:r}}:"south"===c?{firstPoint:p,firstControl:{x:n-8,y:i+32},lastPoint:l,lastControl:{x:o,y:r-32}}:"east"===c?{firstPoint:p,firstControl:{x:n+32,y:i-8},lastPoint:l,lastControl:{x:o-32,y:r}}:{firstPoint:p,firstControl:{x:n-8,y:i-32},lastPoint:l,lastControl:{x:o,y:r+32}}:"west"===c?{firstPoint:p,firstControl:{x:n-32,y:i+8},lastPoint:l,lastControl:{x:o+32,y:r}}:"south"===c?{firstPoint:p,firstControl:{x:n+8,y:i+32},lastPoint:l,lastControl:{x:o,y:r-32}}:"east"===c?{firstPoint:p,firstControl:{x:n+32,y:i+8},lastPoint:l,lastControl:{x:o-32,y:r}}:{firstPoint:p,firstControl:{x:n+8,y:i-32},lastPoint:l,lastControl:{x:o,y:r+32}}:{firstPoint:p,firstControl:{x:n+(o-n)/2,y:i},lastPoint:l,lastControl:{x:n+(o-n)/2,y:r}}},ut=async(t,e,n)=>{const{pos1:o,pos2:i,firstSet:r=!1,direction:s}=n,{x1:a,y1:c,x2:p,y2:l}=await dt(t,e,o,i);let d=0,h=0;"north"===s?h=8:"west"===s?d=8:"east"===s?d=-8:"south"===s&&(h=-8);const{firstPoint:u,firstControl:f,lastControl:g,lastPoint:m}=ht({x1:a+0,x2:p+d,y1:c+0+document.documentElement.scrollTop,y2:l+h+document.documentElement.scrollTop},{direct:!0,firstSet:r,direction:s});return`M ${u.x} ${u.y}C ${f.x} ${f.y}, ${g.x} ${g.y}, ${m.x} ${m.y}`},ft=async({start:t,stop:e,crude:n=!1})=>{const{x1:r,y1:s,x2:a,y2:c}=await dt(t,e),p=((t,e,n,r,s=!0)=>{if(i(t)||i(e)||i(n)||i(r))throw new SyntaxError("Missing input for `angle`");if(o(t)||o(e)||o(n)||o(r))throw TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof n} ${typeof r}`);const a=r-e,c=n-t;let p=Math.atan2(a,c);return p*=180/Math.PI,s&&p<0&&(p+=360),p})(r,s,a,c);return n?(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=45&&t<=135?"south":t>135&&t<=225?"west":t>225&&t<=315?"north":"east"})(p):(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=0&&t<=22.5?"east":t>=22.5&&t<=67.5?"south-east":t>=67.5&&t<=112.5?"south":t>=112.5&&t<=157.5?"south-west":t>=157.5&&t<=202.5?"west":t>=202.5&&t<=247.5?"north-west":t>=247.5&&t<=292.5?"north":t>=292.5&&t<=337.5?"north-east":"east"})(p)};class gt{#t;#n;startElement;stopElement;firstPathElement;secondPathElement;constructor(t,e){this.#e(t,e)}#e(t,e){if(!t||!e)throw Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw Error("stopElement is not in the DOM");if(!document.body.contains(t))throw Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#n=document.getElementById("ph-speccer-path"),!this.#n||!this.#t)throw Error("Missing required SVG element to draw lines. Please see the documentation");const n=et();_(this.#t,{height:`${n}px`}),this.connect()}connect(){this.draw(this.#n)}#o(t){if(!t)throw Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${M()}`,n=t.cloneNode(!1),o=this.startElement.getAttribute("id")||M();return this.startElement.setAttribute("id",o),n.setAttribute("data-start-el",o),n.setAttribute("id",e),n.classList.remove("original"),n.classList.add("speccer"),n}async draw(t){if(!t)throw Error("No path given to draw!");const e=this.#o(t),n=this.#o(t);if(!t.parentNode)throw Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(n,t.nextSibling);const o=await ft({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:i,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,n,o,i;switch(t){case"east":e="right-top",n="left-center",o="right-bottom",i="left-center";break;case"south":e="bottom-left",n="top-center",o="bottom-right",i="top-center";break;case"west":e="left-top",n="right-center",o="left-bottom",i="right-center";break;default:e="top-left",n="bottom-center",o="top-right",i="bottom-center"}return{path1pos1:e,path1pos2:n,path2pos1:o,path2pos2:i}})(o),c=await ut(this.startElement,this.stopElement,{pos1:i,pos2:r,firstSet:!0,direction:o}),p=await ut(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:o});this.firstPathElement.setAttribute("data-direction",o),this.firstPathElement.setAttribute("data-pos1",i),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",c),this.secondPathElement.setAttribute("data-direction",o),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",p)}}window.DrawSVGCurlyBracket=gt;class mt{#t;#n;startElement;stopElement;options;line;constructor(t,e,n={}){this.#e(t,e,n)}#e(t,e,n={}){if(!t||!e)throw Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw Error("stopElement is not in the DOM");if(!document.body.contains(t))throw Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.options=n,this.#t=document.getElementById("ph-speccer-svg"),this.#n=document.getElementById("ph-speccer-path"),!this.#n||!this.#t)throw Error("Missing required SVG element to draw lines. Please see the documentation");const o=et();_(this.#t,{height:`${o}px`}),this.connect()}connect(){this.draw(this.#n)}async draw(t){if(!t)throw Error("No path given to draw!");const e=`ph_draw_path-path-${M()}`,n=t.cloneNode(!1),o=this.startElement.getAttribute("id")||M();this.startElement.setAttribute("id",o),n.setAttribute("id",e),n.setAttribute("data-start-el",o),n.classList.remove("original"),n.classList.add("speccer");const{pin:i}=this.options;if(i?.text&&n.classList.add("text"),!t.parentNode)throw Error("No parentNode found for path");this.line=t.parentNode.insertBefore(n,t.nextSibling);const r=await ft({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:s,pos2:a}=(t=>{let e,n;switch(t){case"east":e="right",n="left";break;case"south":e="bottom",n="top";break;case"west":e="left",n="right";break;default:e="top",n="bottom"}return{pos1:e,pos2:n}})(r),c=await(async(t,e,n)=>{const{pos1:o,pos2:i}=n,{x1:r,y1:s,x2:a,y2:c}=await dt(t,e,o,i),{firstPoint:p,firstControl:l,lastControl:d,lastPoint:h}=ht({x1:r,x2:a,y1:s+document.documentElement.scrollTop,y2:c+document.documentElement.scrollTop},{direction:""});return`M ${p.x} ${p.y}C ${l.x} ${l.y}, ${d.x} ${d.y}, ${h.x} ${h.y}`})(this.startElement,this.stopElement,{pos1:s,pos2:a});this.line.setAttribute("data-direction",r),this.line.setAttribute("data-pos1",s),this.line.setAttribute("data-pos2",a),this.line.setAttribute("d",c)}}window.DrawSVGLine=mt;const yt=t=>parseInt(t,10),wt=t=>yt(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,bt=async(t,e,n,o)=>{await V();const{pin:i={},position:r}=o,{useCurlyBrackets:s,subtle:a,bracket:c,text:p,parent:l,enclose:d}=i,h=wt(e),u=yt(getComputedStyle(e).getPropertyValue("--ph-speccer-measure-size"))||8;const f=await F(e,t);if(d){const{left:t,top:e,height:n,width:o}=f.absolute();return{left:`${t}px`,top:`${e}px`,height:`${n}px`,width:`${o}px`}}if((l||p)&&!c&&!s&&!a){if(r===m.Right){const{top:t}=f.fromRight({center:!0});await V();const{left:e,width:o}=n.getBoundingClientRect();return{left:`${e+o+h}px`,top:`${t}px`}}if(r===m.Bottom){const{left:t}=f.toBottom({center:!0});await V();const{top:e,height:o}=n.getBoundingClientRect();return{left:`${t}px`,top:`${e+o+h}px`}}if(r===m.Left){const{top:t}=f.fromLeft({center:!0});await V();const{left:e}=n.getBoundingClientRect();return{left:e-1.5*h-(p?170:0)+"px",top:`${t}px`}}const{left:t}=f.fromTop({center:!0});await V();const{top:e}=n.getBoundingClientRect();return{left:`${t}px`,top:e-1.5*h+"px"}}if(r===m.Left){if(c&&!s){const{left:t,top:e,height:n}=f.fromLeft({sourceWidth:u});return{left:`${t}px`,top:`${e}px`,height:`${n}px`}}const{left:t,top:e}=f.fromLeft({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(r===m.Right){if(c&&!s){const{left:t,top:e,height:n}=f.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${n}px`}}const{left:t,top:e}=f.fromRight({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(r===m.Bottom){if(c&&!s){const{left:t,top:e,width:n}=f.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${n}px`}}const{left:t,top:e}=f.fromBottom({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(c&&!s){const{left:t,top:e,width:n}=f.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${n}px`}}const{left:g,top:y}=f.fromTop({center:!0,modifier:s?h/1.5:h});return{left:`${g}px`,top:`${y}px`}},xt=async(t,e,n,o)=>{if(!t)return;if("pin"!==o.type||!o.pin)return;const i=`speccer-${o.slug}-${t.getAttribute("id")||M()}`,r=tt(n,o,i);t.setAttribute("data-speccer-element-id",i),document.body.appendChild(r);const s=await bt(t,r,e,o);await _(r,s);const a=o.pin.text&&null!==t.getAttribute("data-speccer-title"),c=o.pin.parent&&!o.pin.enclose&&!o.pin.bracket&&!a;return o.pin.useSVGLine?(new mt(t,r,o),c&&new lt(t,5,o)):o.pin.useCurlyBrackets&&new gt(t,r),i};let $t=0;const Et=async(t,e)=>{if(!t)return;const n=t.querySelectorAll('[data-speccer^="pin"]');if(!n||0===n.length)return;const o=t.getAttribute("data-speccer-literals")||window.SPECCER_LITERALS||a;[...n].filter((async t=>!O(t))).forEach((async(n,i)=>{const r=((t,e)=>{let n=e[t];return 0===t&&($t=0),n||(n=`${e[$t]}${e[$t].toLowerCase()}`,$t++),n})(i,o),s=n.getAttribute("data-speccer")||"";await V();const a=getComputedStyle(n),c=I(s,a,e),p=((t,e,n)=>{const{pin:o}=n;if(!o)return t;const{text:i}=o;if(!i||null===e.getAttribute("data-speccer-title"))return t;const r=e.getAttribute("data-speccer-title"),s=e.getAttribute("data-speccer-description"),a=0===e.nodeName.indexOf("H")?`<span class="ph-speccer heading">${e.nodeName}</span>`:"";return!s&&r?`${a}<span class="ph-speccer title">${r}</span>`:s&&r?`${a}<span class="ph-speccer title">${r}</span><span class="ph-speccer description">${s.replaceAll("\\n","<br/>")}</span>`:t})(r,n,c);await xt(n,t,p,c)}))},At=(t="",e="span")=>{const n=document.createElement(e),o=document.createTextNode(`${t}px`);return n.appendChild(o),n.setAttribute("title",`${t}px`),r(n,"ph-speccer speccer spacing"),n},St=async(t,e)=>{if(!t)return;if(O(t))return;const n=t.getAttribute("data-speccer")||"",o=await X(t),i=I(n,o,e);if("spacing"!==i.type||!i.spacing)return;const a=((t,e)=>{const{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r,paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}=t;return e?.spacing?.padding?{paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}:e?.spacing?.margin?{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r}:{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r,paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}})(o,i),c=Object.keys(a).filter((t=>"0px"!==a[t]));if(!c.length)return;t.classList.add("is-specced");const p=`speccer-spacing-${t.getAttribute("id")||M()}`;t.setAttribute("data-speccer-element-id",p),c.forEach((async e=>{const n=yt(a[e]),o=At(n);o.setAttribute("data-speccer-id",p);const c=(t=>t.includes("Top")?t.replace("Top"," top"):t.includes("Right")?t.replace("Right"," right"):t.includes("Bottom")?t.replace("Bottom"," bottom"):t.includes("Left")?t.replace("Left"," left"):"")(e);r(o,s(c,{bound:!!i?.spacing?.bound})),document.body.appendChild(o);const l=await(async(t,e,n,o)=>{await V();const i=n.getBoundingClientRect(),r=await D(n),s=o?.spacing?.bound?0:96,a=o?.spacing?.bound?0:48;return"marginTop"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top-e+"px"}:"marginRight"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+parseInt(i.width+"",10)+"px",top:r.top+"px"}:"marginBottom"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+parseInt(i.height+"",10)+"px"}:"marginLeft"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}:"paddingTop"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+"px"}:"paddingBottom"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+(parseInt(i.height+"",10)-e)+"px"}:"paddingRight"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+(parseInt(i.width+"",10)-e)+"px",top:r.top+"px"}:"paddingLeft"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"}:void 0})(e,n,t,i);await _(o,l)}))},Ct=(t,e=3)=>parseFloat(String(t)).toFixed(e),kt=(t,e,n)=>{const o=document.createElement("div"),{typography:i,position:a}=e,c=s("ph-speccer speccer typography",{syntax:i?.useSyntaxHighlighting||!1,[a]:!0});return o.setAttribute("id",n),o.setAttribute("data-speccer-id",n),o.innerHTML=t,r(o,c),o},vt=async(t,e)=>{if(!t)return;if(O(t))return;const n=t.getAttribute("data-speccer")||"";await V();const o=I(n,getComputedStyle(t),e);if("typography"!==o.type||!o.typography)return;t.classList.add("is-specced");const i=await(async(t,e=!1)=>{const n=(t=>{const{lineHeight:e,letterSpacing:n,fontFamily:o,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:n,fontFamily:o,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await X(t));if(e){const t=(n.fontFamily||"").split(",").map((t=>t.includes('"\'"')?`<span class="token string">${t}</span>`:t)).join('<span class="token punctuation">, </span>'),e=`<span class="token number">${parseInt(n.fontSize||"NaN",10)}</span><span class="token unit">px</span> <span class="token operator">/</span> <span class="token number">${parseInt(n.fontSize||"NaN",10)/16}</span><span class="token unit">rem</span>`,o=n.letterSpacing?n.letterSpacing.includes("px")?`<span class="token number">${parseInt(n.letterSpacing,10)}</span><span class="token unit">px</span>`:n.letterSpacing:"",i=n.lineHeight?"normal"!==n.lineHeight?`<span class="token number">${parseInt(n.lineHeight,10)}</span><span class="token unit">px</span> <span class="token operator">/</span> <span class="token number">${parseInt(n.lineHeight,10)/16}</span><span class="token unit">rem</span>`:"normal":"";return`\n<pre class="language-css" tabindex="-1"><code class="language-css"><span class="token selector"><span class="token class">.typography</span></span> <span class="token punctuation">{</span>\n <span class="token property">font-family</span><span class="token punctuation">:</span> ${t}<span class="token punctuation">;</span>\n <span class="token property">font-size</span><span class="token punctuation">:</span> ${e}<span class="token punctuation">;</span>\n <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">${n.fontWeight}</span><span class="token punctuation">;</span>\n <span class="token property">font-variation-settings</span><span class="token punctuation">:</span> ${n.fontVariationSettings}<span class="token punctuation">;</span>\n <span class="token property">line-height</span><span class="token punctuation">:</span> ${i}<span class="token punctuation">;</span>\n <span class="token property">letter-spacing</span><span class="token punctuation">:</span> ${o}<span class="token punctuation">;</span>\n <span class="token property">font-style</span><span class="token punctuation">:</span> ${n.fontStyle}<span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre>`}return`\ntypography: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${n.fontFamily};</li> <li><span class="property">font-size:</span> ${n.fontSize} / ${parseInt(n.fontSize||"NaN",10)/16}rem;</li> <li><span class="property">font-weight:</span> ${n.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${n.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${"normal"!==n.lineHeight?`${parseInt(n.lineHeight||"NaN",10)}px / ${parseInt(n.lineHeight||"NaN",10)/16}rem`:"normal"};</li> <li><span class="property">letter-spacing:</span> ${n.letterSpacing};</li> <li><span class="property">font-style:</span> ${n.fontStyle};</li></ul>}`})(t,o.typography.useSyntaxHighlighting),r=`speccer-${o.slug}-${t.getAttribute("id")||M()}`;t.setAttribute("data-speccer-element-id",r);const s=kt(i,o,r);document.body.appendChild(s);const a=await(async(t,e,n)=>{const o=e.getBoundingClientRect(),i=wt(n),r=n.getBoundingClientRect(),s=await D(e),{typography:a,position:c}=t;if(a&&c===w.Right)return{left:s.left+o.width+i+"px",top:Ct(W(s.top,r,o))+"px"};if(a&&c===w.Top)return{left:Ct(j(s.left,r,o))+"px",top:s.top-r.height-i+"px"};if(a&&c===w.Bottom)return{left:Ct(j(s.left,r,o))+"px",top:s.top+o.height+i+"px"};return{left:s.left-r.width-i+"px",top:Ct(W(s.top,r,o))+"px"}})(o,t,s);_(s,a)},Pt=t=>{const e=()=>((t,e,n=!1)=>{let o;return function(i,...r){const s=n&&!o;o&&clearTimeout(o),o=setTimeout((function(){o=null,n||t.apply(i,r)}),e),s&&t.apply(i,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},Lt=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},Bt=()=>{const t=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(St(n.target),e.unobserve(n.target))}));for(const e of document.querySelectorAll(`[${c}^="${p}"],[${c}^="${p}"] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)`))t.observe(e);const e=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(Q(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${c}^="${l}"]`))e.observe(t);const n=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(Z(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${c}^="${h}"]`))n.observe(t);const o=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(vt(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${c}^="${d}"]`))o.observe(t);const i=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(K(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${c}^="${u}"]`))i.observe(t);const r=new IntersectionObserver((async(t,e)=>{for(const n of t)n.intersectionRatio>0&&(await Et(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${c}="${f}"]`))r.observe(t)},Rt=t=>{window.speccer=t},Tt=t=>{const e=document.currentScript;if(e){const n=e.getAttribute("src");n?.includes("speccer.js")&&(e.hasAttribute("data-manual")?Rt(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?Lt(t):e.hasAttribute("data-lazy")?Bt():Lt(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||Pt(t))}},Nt=["alt","altgraph","capslock","control","fn","fnlock","hyper","meta","numlock","os","scrolllock","shift","super","symbol","command","ctrl","altgr","symbollock"],qt=["escape","esc","enter","return","⏎","␛"],Ht=async(t,e,n)=>{await V();const o=wt(n),i=await F(n,e);if("tabstops"===t){let{left:t,top:e}=i.fromTop();return t-=32,e+=32,t<=0&&(t=32),e<=0&&(e=32),{left:`${t}px`,top:`${e}px`}}if("landmark"===t||"autocomplete"===t||"headings"===t){let{left:t,top:e}=i.fromLeft();return t-=o,t<=0&&(t=o),e<=0&&(e=o),{left:`${t}px`,top:`${e}px`}}if("region"===t){const{left:t,top:e,height:n,width:o}=i.fromTop();return{height:`${n}px`,width:`${o}px`,left:`${t}px`,top:`${e}px`}}if("shortcut"===t){const{left:t,top:e}=i.fromBottom();return{left:`${t}px`,top:`${e}px`}}const{left:r,top:s}=i.fromTop({center:!0,modifier:o});return{left:r-32+"px",top:s-32+"px"}},It=async(t,e,n)=>{if(!t||!t.checkVisibility())return;const o=((t="tabstops",e,n="span")=>{const o=document.createElement(n),i=s("ph-speccer speccer a11y",{tabstops:"tabstops"===t,landmark:"landmark"===t,autocomplete:"autocomplete"===t,headings:"headings"===t,region:"region"===t});if("landmark"===t&&e){const t=document.createTextNode(String(e));o.appendChild(t)}return r(o,i),o})(n,e);if("landmark"===n){const e=(t=>{if(!t)return"";if(t.role&&""!==t.role)return t.role;const e=t.nodeName.toLowerCase();return["header","footer","section","form","main","nav","aside"].includes(e)?e:"N/A"})(t),n=t.nodeName.toLowerCase();o.innerHTML=`&lt;${n} role="${e}"&gt;`}if("autocomplete"===n){const e=t.getAttribute("autocomplete")||"";o.innerHTML=`autocomplete="${e}"`}"headings"===n&&(o.innerHTML=t.nodeName,o.classList.add(t.nodeName.toLowerCase())),"tabstops"===n&&o.setAttribute("data-speccer-a11y-tabstops",e);const i=`speccer-a11y-${t.getAttribute("id")||M()}`;o.setAttribute("data-speccer-id",i),document.body.appendChild(o);const a=await Ht(n,t,o);await _(o,a)},Mt=async(t,e)=>{const n=e.split(/\s\+\s/).map((t=>t.trim())),o=document.createElement("div"),i=s("ph-speccer speccer a11y shortcut-holder");r(o,i);for(const t of n){const e=document.createElement("kbd"),n=document.createTextNode(t),i=s("ph-speccer speccer a11y shortcut",{modifier:Nt.includes(t.toLowerCase()),physical:qt.includes(t.toLowerCase())});r(e,i),e.appendChild(n);const a=`speccer-a11y-shortcut-${M()}`;o.setAttribute("data-speccer-id",a),o.appendChild(e)}document.body.appendChild(o);const a=await Ht("shortcut",t,o);await _(o,a)},Ot=t=>{const e=t.getAttribute("data-speccer-element-id");if(!e)return;const n=document.getElementById(e)||document.querySelectorAll(`[data-speccer-id="${e}"]`);if(n)if(Object.prototype.isPrototypeOf.call(NodeList.prototype,n))[...n].forEach((t=>{t.remove(),t.classList.remove("is-specced")}));else if(n.classList.contains("curly")||n.classList.contains("svg")){const e=t.getAttribute("id");document.querySelectorAll(`#ph-speccer-svg path[data-start-el="${e}"]`).forEach((t=>t.remove()))}},Vt={create:Y,element:K},zt={create:At,element:St},Gt={createPinElement:tt,pinElement:xt,pinElements:Et},jt={create:J,element:Q},Wt={create:U,element:Z},Dt={create:kt,element:vt},Ft={dom:Lt,lazy:Bt,manual:Rt,activate:Tt},_t=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".ph-speccer.speccer");const t=document.querySelectorAll(`[${c}^="${p}"]`),e=document.querySelectorAll(`[${c}^="${l}"]`),n=document.querySelectorAll(`[${c}^="${d}"]`),o=document.querySelectorAll(`[${c}="${f}"]`),i=document.querySelectorAll(`[${c}^="${h}"]`),r=document.querySelectorAll(`[${c}^="${u}"]`);for(const t of i)Z(t);for(const t of r)K(t);for(const e of t)if(St(e),e.hasChildNodes()){const t=e.querySelectorAll("*:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody):not([data-speccer])"),n=e.getAttribute("data-speccer")||"";if(t?.length)for(const e of t)e.setAttribute("data-speccer",n),St(e)}for(const t of e)Q(t);for(const t of n)vt(t);for(const t of o)Et(t);(()=>{const t=document.querySelectorAll('[data-speccer*="a11y tabstops"]'),e=document.querySelectorAll('[data-speccer*="a11y landmark"]'),n=document.querySelectorAll('[data-speccer*="a11y shortcut"]'),o=document.querySelectorAll('[data-speccer*="a11y autocomplete"]'),i=document.querySelectorAll('[data-speccer*="a11y headings"]');if(n.length)for(const t of n){const e=t.getAttribute("data-speccer-a11y-shortcut");e&&""!==e&&!O(t)&&Mt(t,e)}if(t.length)for(const e of t){const t=e.querySelectorAll("\n a[href], area[href], input:not([disabled]):not([tabindex='-1']),\n button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']),\n textarea:not([disabled]):not([tabindex='-1']),\n iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]\n");for(const[e,n]of t.entries()){if(!O(n)){It(n,e+1,"tabstops");continue}const t=n.getAttribute("id");if(!t)continue;const o=document.querySelector(`[for="${t}"]`);o&&!O(o)&&It(o,e+1,"tabstops")}}if(o.length)for(const t of o){const e=t.querySelectorAll("[autocomplete]");for(const t of e)O(t)||It(t,null,"autocomplete")}if(i.length)for(const t of i){const e=t.querySelectorAll('h1,h2,h3,h4,h5,h6, [role="heading"]');for(const t of e)O(t)||It(t,null,"headings")}if(e.length)for(const t of e){const e=t.querySelectorAll('\nheader, footer, section, form, main, nav, aside, [role="section"], [role="banner"],\n[role="complementary"], [role="contentinfo"], [role="form"], [role="main"],\n[role="navigation"], [role="region"], [role="search"]\n');for(const[t,n]of e.entries())O(n)||(It(n,t+1,"landmark"),It(n,null,"region"))}})()};Tt(_t);export{_t as default,Vt as grid,Wt as mark,jt as measure,Ft as modes,Gt as pin,Ot as removeSpeccerElement,zt as spacing,Dt as typography};
28
- //# sourceMappingURL=speccer.esm.js.map
package/dist/speccer.js CHANGED
@@ -2,9 +2,9 @@
2
2
  * @phun-ky/speccer
3
3
  * A script to annotate, show spacing specs and to display typography information in documentation/website on HTML elements
4
4
  * @author Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>
5
- * @version 11.2.8
5
+ * @version 11.2.10
6
6
  * @license
7
- * Copyright (c) 2018 Alexander Vassbotn Røyne-Helgesen
7
+ * Copyright (c) 2018-2025 Alexander Vassbotn Røyne-Helgesen
8
8
  *
9
9
  * Permission is hereby granted, free of charge, to any person obtaining a copy
10
10
  * of this software and associated documentation files (the "Software"), to deal
@@ -25,4 +25,3 @@
25
25
  * SOFTWARE.
26
26
  */
27
27
  !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).speccer={})}(this,(function(t){"use strict";const e=t=>"string"==typeof t,n=t=>!e(t),o=t=>"number"==typeof t,i=t=>!o(t),r=t=>void 0===t,s=(t,e,n="noop")=>{if(!t)return;if(!e||e&&!e.length)return;const o=e.trim().split(" ").filter((t=>t!==n)).filter((t=>""!==t)).map((t=>t.trim()));t.classList.add(...o)},a=(t,e)=>t?!e&&n(t)?Object.keys(t).filter((e=>t[e])).join(" ").trim():`${t.trim()} ${e?Object.keys(e).filter((t=>e[t])).join(" "):""}`.trim():"",c=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],p="data-speccer",l="spacing",d="measure",h="typography",u="mark",f="grid",g="pin-area";var m,y,w,b,x,$,E;!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(m||(m={})),function(t){t.Pin="pin",t.Parent="parent",t.Text="text",t.Enclose="enclose",t.Subtle="subtle",t.Bracket="bracket",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(y||(y={})),function(t){t.Measure="measure",t.Slim="slim",t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(w||(w={})),function(t){t.Typography="typography",t.Syntax="syntax",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(b||(b={})),function(t){t.Spacing="spacing"}(x||(x={})),function(t){t.Mark="mark"}($||($={})),function(t){t.Grid="grid"}(E||(E={}));const A=t=>t.split(" "),S=t=>{if(null===t)return!1;return A(t).includes(y.Bracket)},C=t=>{if(null===t)return!1;return A(t).includes(y.Enclose)},k=t=>{if(null===t)return!1;return A(t).includes(y.Subtle)},v=t=>{if(null===t)return!1;return A(t).includes(y.Parent)},P=t=>{if(null===t)return!1;return A(t).includes(y.Text)},L=t=>{if(null===t)return!1;return A(t).includes(w.Height)},B=t=>{if(null===t)return!1;return A(t).includes(w.Slim)},R=t=>{if(null===t)return!1;return A(t).includes(w.Width)},T=t=>{if(null===t)return!1;const e=A(t);return(v(t)&&!C(t)&&!S(t)||P(t)||e.includes(y.SVG))&&!N(t)},N=t=>{if(null===t)return!1;const e=A(t);return e.includes(y.Curly)&&e.includes(y.Bracket)},q=t=>!!t&&t.split(" ").includes(b.Syntax),M=(t,n)=>(t=>null!==t&&t.split(" ").includes(y.Pin))(t)?"pin":((t,n)=>null!==t&&t.split(" ").includes(E.Grid)&&e(n.display)&&("grid"===n.display||(n.display||"").includes("grid")))(t,n)?"grid":(t=>null!==t&&t.split(" ").includes($.Mark))(t)?"mark":(t=>null!==t&&t.split(" ").includes(w.Measure))(t)?"measure":(t=>null!==t&&t.split(" ").includes(x.Spacing))(t)?"spacing":(t=>null!==t&&t.split(" ").includes(b.Typography))(t)?"typography":"pin",H=t=>(t=>null!==t&&A(t).includes(y.Left))(t)?"left":(t=>null!==t&&A(t).includes(y.Right))(t)?"right":(t=>null!==t&&A(t).includes(y.Bottom))(t)?"bottom":"top",I=(t,e,n)=>{const o=M(t,e),i={slug:(r=t,r.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").trim().toLowerCase().replace(/[^a-z0-9 -]/g,"").replace(/\s+/g," ").replace(/(?:^\w|[A-Z]|\b\w)/g,((t,e)=>0===e?t.toLowerCase():t.toUpperCase())).replace(/\s+/g,"")),position:H(t),type:o};var r;if("pin"===o&&(i.pin={bracket:S(t),enclose:C(t),subtle:k(t),parent:v(t),text:P(t),useSVGLine:T(t),useCurlyBrackets:N(t)}),"measure"===o&&(i.measure={slim:B(t),height:L(t),width:R(t)}),"typography"===o&&(i.typography={useSyntaxHighlighting:q(t)}),"grid"===o){const e=(t=>t?.includes("columns")?"columns":t?.includes("rows")?"rows":"both")(t);i.grid={toggle:e,both:"both"===e,rows:"rows"===e,columns:"columns"===e}}if("spacing"===o){const e=(t=>t?.includes("margin")?"margin":t?.includes("padding")?"padding":"both")(t);i.spacing={both:"both"===e,margin:"margin"===e,padding:"padding"===e,bound:t.includes("bound")}}return{...i,...n}},O=()=>"_"+Math.random().toString(36).substring(2,11),V=t=>!t.checkVisibility({opacityProperty:!0,checkVisibilityCSS:!0}),z=()=>new Promise(requestAnimationFrame),G=async(t,e,n)=>{await z();return getComputedStyle(t)[e]===n},j=async(t,e,n)=>{if(!t.parentElement)return null;return await G(t.parentElement,e,n)?t.parentElement:await j(t.parentElement,e,n)},W=(t,e,n)=>t-e.width/2+n.width/2,D=(t,e,n)=>t-e.height/2+n.height/2,F=async t=>{await z();let e=t.getBoundingClientRect(),n=e.top+window.scrollY;const o=e.left+window.scrollX,i=await(async t=>await j(t,"position","sticky"))(t);if(await(async t=>await G(t,"position","sticky"))(t)){const o=t.style.position;await z(),t.style.position="relative",await z(),e=t.getBoundingClientRect(),n=e.top,await z(),t.style.position=o}else if(i){const o=i.style.position;await z(),i.style.position="relative",await z(),e=t.getBoundingClientRect(),n=e.top,await z(),i.style.position=o}return{height:e.height,width:e.width,top:n,left:o}},_=async(t,e)=>{await z();const n=t.getBoundingClientRect(),o=await F(e),i=await(async(t,e)=>{await z();const n=t.getBoundingClientRect();await z();const o=e.getBoundingClientRect(),i=o.top+window.scrollY,r=o.left+window.scrollX;return{height:o.height,width:o.width,top:D(i,n,o),left:W(r,n,o)}})(t,e),r=o.height,s=o.width,a=n.height,c=n.width;return{absolute:()=>({top:o.top,left:o.left,height:r,width:s}),toTop:({center:t=!1,sourceHeight:e=a,modifier:n=0}={})=>({top:o.top+e+n,left:t?i.left:o.left,height:r,width:s}),fromTop:({center:t=!1,sourceHeight:e=a,modifier:n=0}={})=>({top:o.top-e-n,left:t?i.left:o.left,height:r,width:s}),toBottom:({center:t=!1,sourceHeight:e=a,targetHeight:n=r,modifier:c=0}={})=>({top:o.top+n-(e+c),left:t?i.left:o.left,height:r,width:s}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:n=0}={})=>({top:o.top+e+n,left:t?i.left:o.left,height:r,width:s}),toLeft:({center:t=!1,sourceWidth:e=c,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left+e+n,height:r,width:s}),fromLeft:({center:t=!1,sourceWidth:e=c,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left-e-n,height:r,width:s}),toRight:({center:t=!1,sourceWidth:e=c,targetWidth:n=s,modifier:a=0}={})=>({top:t?i.top:o.top,left:o.left+n-(e+a),height:r,width:s}),fromRight:({center:t=!1,targetWidth:e=s,modifier:n=0}={})=>({top:t?i.top:o.top,left:o.left+e+n,height:r,width:s})}},X=async(t,n)=>{var i;!t||!n||e(n)||o(n)||(i=n,"boolean"==typeof i)||Array.isArray(n)&&!n.length||!Object.keys(n).length&&n.constructor===Object||(await z(),Array.isArray(n)&&(n=n.reduce(((t,e)=>(t[e.key]=e.value,t)),{})),Object.assign(t.style,n))},Y=async t=>(await z(),getComputedStyle(t,null)),K=async(t,e,n)=>{await z();const{grid:o}=n;if(!o)return;const{toggle:i}=o,{height:r,width:a}=t.getBoundingClientRect(),{top:c,left:p}=await F(t),{gridTemplateColumns:l,gridTemplateRows:d,padding:h}=e,u=`speccer-${n.slug}-${t.getAttribute("id")||O()}`;if(t.setAttribute("data-speccer-element-id",u),"columns"===i||"both"===i){const t=parseInt(e.columnGap||"0"),n=document.createElement("div");document.documentElement.style.setProperty("--ph-speccer-grid-gap-original",`${t}px`),document.documentElement.style.setProperty("--ph-speccer-grid-gap",`${t<24?24:t}px`),t<24&&n.classList.add("speccer-small-grid"),n.setAttribute("data-speccer-id",u),s(n,"ph-speccer speccer speccer-grid-container"),X(n,{height:`${r+64}px`,width:`${a}px`,left:`${p}px`,top:c-32+"px",padding:h,gridTemplateColumns:l});const o=l?.split(" ").length||0;for(let t=0;t<o;t++){const t=document.createElement("div");s(t,"ph-speccer speccer speccer-grid-item"),n.appendChild(t)}document.body.appendChild(n)}if("rows"===i||"both"===i){const t=parseInt(e.rowGap||"0"),n=document.createElement("div");document.documentElement.style.setProperty("--ph-speccer-grid-row-gap-original",`${t}px`),document.documentElement.style.setProperty("--ph-speccer-grid-row-gap",`${t<24?24:t}px`),t<24&&n.classList.add("speccer-small-grid"),n.setAttribute("data-speccer-id",u),n.classList.add("ph-speccer"),n.classList.add("speccer"),n.classList.add("speccer-grid-row-container"),s(n,"ph-speccer speccer speccer-grid-row-container"),X(n,{width:`${a+64}px`,height:`${r}px`,top:`${c}px`,left:p-32+"px",padding:h,gridTemplateRows:d});const o=d?.split(" ").length||0;for(let t=0;t<o;t++){const t=document.createElement("div");s(t,"ph-speccer speccer speccer-grid-row-item"),n.appendChild(t)}document.body.appendChild(n)}},U=async(t,e)=>{if(!t)return;if(V(t))return;const n=t.getAttribute(p)||"",o=await Y(t),i=I(n,o,e);"grid"===i.type&&i.grid&&(await z(),await K(t,o,i))},Z=(t,e="span")=>{const n=document.createElement(e);return n.setAttribute("id",t),s(n,"ph-speccer speccer mark"),n},J=async t=>{if(!t)return;if(V(t))return;const e=t.getAttribute(p)||"";await z();const n=I(e,getComputedStyle(t));if("mark"!==n.type)return;const o=`speccer-${n.slug}-${t.getAttribute("id")||O()}`;t.setAttribute("data-speccer-element-id",o);const i=Z(o);i.setAttribute("data-speccer-id",o),document.body.appendChild(i);const r=await _(i,t),{left:s,top:a,height:c,width:l}=r.absolute(),d={left:`${s}px`,top:`${a}px`,height:`${c}px`,width:`${l}px`};await X(i,d)},Q=(t="",e,n,o="span")=>{const i=document.createElement(o);i.setAttribute("title",`${t}px`),i.setAttribute("id",n),i.setAttribute("data-speccer-id",n),i.setAttribute("data-measure",`${parseInt(String(t),10)}px`);const{measure:r,position:c}=e,p=a("ph-speccer speccer measure",{height:r?.height||!1,width:r?.width||!1,slim:r?.slim||!1,[c]:!0});return s(i,p),i},tt=async(t,e)=>{if(!t)return;if(V(t))return;const n=t.getAttribute("data-speccer")||"";await z();const o=I(n,getComputedStyle(t),e);if("measure"!==o.type||!o.measure)return;const{measure:i,position:r}=o;await z();const s=t.getBoundingClientRect(),a=i.slim?0:48,c=i.slim?0:96,p=`speccer-${o.slug}-${t.getAttribute("id")||O()}`;if(t.setAttribute("data-speccer-element-id",p),i.width)if(r===w.Bottom){const e=Q(s.width,o,p);document.body.appendChild(e);const n=await _(e,t);if(i.slim){const{left:t,top:o,width:i}=n.fromBottom({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`})}else{const{left:t,top:o,width:i,height:r}=n.absolute({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`,height:`${r+a}px`})}}else{const e=Q(s.width,o,p);document.body.appendChild(e);const n=await _(e,t);if(i.slim){const{left:t,top:o,width:i}=n.fromTop({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,width:`${i}px`})}else{const{left:t,top:o,width:i,height:r}=n.absolute({center:!1});await X(e,{left:`${t}px`,top:o-a+"px",width:`${i}px`,height:`${r+a}px`})}}else if(i.height)if(r===w.Right){const e=Q(s.height,o,p);document.body.appendChild(e);const n=await _(e,t);if(i.slim){const{left:t,top:o,height:i}=n.fromRight({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`})}else{const{left:t,top:o,height:i,width:r}=n.absolute({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`,width:`${r+c}px`})}}else{const e=Q(s.height,o,p);document.body.appendChild(e);const n=await _(e,t);if(i.slim){const{left:t,top:o,height:i}=n.fromLeft({center:!1});await X(e,{left:`${t}px`,top:`${o}px`,height:`${i}px`})}else{const{left:t,top:o,height:i,width:r}=n.absolute({center:!1});await X(e,{left:t-c+"px",top:`${o}px`,height:`${i}px`,width:`${r+c}px`})}}},et=(t="",e,n="",o="span")=>{const i=document.createElement(o),r={},{position:c,pin:p={}}=e,{useSVGLine:l,useCurlyBrackets:d,text:h,parent:u,bracket:f,enclose:g,subtle:m}=p;r.text=h,r.parent=u,r.bracket=f,r.enclose=g,r.subtle=m,r.svg=l,r.curly=d,r[c]=!0,!u||f||d||m||(r.svg=!0),!f&&!g||f&&d?i.innerHTML=t:(f||g)&&i.setAttribute("data-pin-counter",t);const y=a("ph-speccer speccer pin",r);return s(i,y),i.setAttribute("id",n),i.setAttribute("data-speccer-id",n),i},nt=()=>{const{body:t,documentElement:e}=document;return Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight)},ot=t=>t.top,it=t=>t.left+t.width,rt=t=>t.top+t.height,st=t=>t.left,at=t=>t.left+t.width/2,ct=t=>t.top+t.height/2,pt={center:t=>({x:at(t),y:ct(t)}),top:t=>({x:at(t),y:ot(t)}),right:t=>({x:it(t),y:ct(t)}),bottom:t=>({x:at(t),y:rt(t)}),left:t=>({x:st(t),y:ct(t)}),"right-top":t=>({x:it(t),y:ot(t)}),"right-bottom":t=>({x:it(t),y:rt(t)}),"left-top":t=>({x:st(t),y:ot(t)}),"left-bottom":t=>({x:st(t),y:rt(t)}),"top-left":t=>({x:st(t),y:ot(t)}),"top-right":t=>({x:it(t),y:ot(t)}),"bottom-left":t=>({x:st(t),y:rt(t)}),"bottom-right":t=>({x:it(t),y:rt(t)}),"top-center":t=>({x:at(t),y:ot(t)}),"right-center":t=>({x:it(t),y:ct(t)}),"bottom-center":t=>({x:at(t),y:rt(t)}),"left-center":t=>({x:st(t),y:ct(t)})},lt=async(t,e="center")=>{if(!e)throw Error("No position given");if(n(e))throw Error("The position given is not the required type: pos: "+typeof e);const o=["center","left","right","top","bottom","right-top","right-bottom","left-top","left-bottom","top-left","top-right","bottom-left","bottom-right","top-center","right-center","bottom-center","left-center"];if(!o.includes(e))throw Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await z();const i=t.getBoundingClientRect();return pt[e](i)};class dt{#t;el;circle;radius;options;constructor(t,e,n){this.#e(t,e,n)}#e(t,e,n){if(!t||!e||!n)throw Error("Missing inputs el or radius or options");if(!document.body.contains(t))throw Error("el is not in the DOM");if(this.el=t,this.radius=e,this.options=n,this.#t=document.getElementById("ph-speccer-svg"),!this.#t)throw Error("Missing required SVG element to draw circles. Please see the documentation");const o=nt();X(this.#t,{height:`${o}px`}),this.draw()}async draw(){const t=`ph_draw-circle-${O()}`;this.circle=document.createElementNS("http://www.w3.org/2000/svg","circle");const e=this.el.getAttribute("id")||O();if(this.el.setAttribute("id",e),this.circle.setAttribute("id",t),this.circle.setAttribute("data-el",e),this.circle.classList.add("ph-speccer"),this.circle.classList.add("speccer"),this.circle.classList.add("circle"),!this.#t)throw Error("No parentNode found for circle");this.#t.appendChild(this.circle);const{x:n,y:o}=await lt(this.el,this.options.position);this.circle.setAttribute("r",this.radius+""),this.circle.setAttribute("cx",Math.round(n)+""),this.circle.setAttribute("cy",Math.round(o+document.documentElement.scrollTop)+""),this.circle.setAttribute("fill","currentColor")}}window.DrawCircle=dt;const ht=async(t,e,n="center",o="center")=>{if(!t||!e)throw Error("No element given");const{x:i,y:r}=await lt(t,n),{x:s,y:a}=await lt(e,o);return{x1:i,y1:r,x2:s,y2:a}},ut=(t,e)=>{const{x1:n,x2:o,y1:i,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:c}=e,p={x:n,y:i},l={x:o,y:r};return s?a?"west"===c?{firstPoint:p,firstControl:{x:n-32,y:i-8},lastPoint:l,lastControl:{x:o+32,y:r}}:"south"===c?{firstPoint:p,firstControl:{x:n-8,y:i+32},lastPoint:l,lastControl:{x:o,y:r-32}}:"east"===c?{firstPoint:p,firstControl:{x:n+32,y:i-8},lastPoint:l,lastControl:{x:o-32,y:r}}:{firstPoint:p,firstControl:{x:n-8,y:i-32},lastPoint:l,lastControl:{x:o,y:r+32}}:"west"===c?{firstPoint:p,firstControl:{x:n-32,y:i+8},lastPoint:l,lastControl:{x:o+32,y:r}}:"south"===c?{firstPoint:p,firstControl:{x:n+8,y:i+32},lastPoint:l,lastControl:{x:o,y:r-32}}:"east"===c?{firstPoint:p,firstControl:{x:n+32,y:i+8},lastPoint:l,lastControl:{x:o-32,y:r}}:{firstPoint:p,firstControl:{x:n+8,y:i-32},lastPoint:l,lastControl:{x:o,y:r+32}}:{firstPoint:p,firstControl:{x:n+(o-n)/2,y:i},lastPoint:l,lastControl:{x:n+(o-n)/2,y:r}}},ft=async(t,e,n)=>{const{pos1:o,pos2:i,firstSet:r=!1,direction:s}=n,{x1:a,y1:c,x2:p,y2:l}=await ht(t,e,o,i);let d=0,h=0;"north"===s?h=8:"west"===s?d=8:"east"===s?d=-8:"south"===s&&(h=-8);const{firstPoint:u,firstControl:f,lastControl:g,lastPoint:m}=ut({x1:a+0,x2:p+d,y1:c+0+document.documentElement.scrollTop,y2:l+h+document.documentElement.scrollTop},{direct:!0,firstSet:r,direction:s});return`M ${u.x} ${u.y}C ${f.x} ${f.y}, ${g.x} ${g.y}, ${m.x} ${m.y}`},gt=async({start:t,stop:e,crude:n=!1})=>{const{x1:o,y1:s,x2:a,y2:c}=await ht(t,e),p=((t,e,n,o,s=!0)=>{if(r(t)||r(e)||r(n)||r(o))throw new SyntaxError("Missing input for `angle`");if(i(t)||i(e)||i(n)||i(o))throw TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof n} ${typeof o}`);const a=o-e,c=n-t;let p=Math.atan2(a,c);return p*=180/Math.PI,s&&p<0&&(p+=360),p})(o,s,a,c);return n?(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=45&&t<=135?"south":t>135&&t<=225?"west":t>225&&t<=315?"north":"east"})(p):(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=0&&t<=22.5?"east":t>=22.5&&t<=67.5?"south-east":t>=67.5&&t<=112.5?"south":t>=112.5&&t<=157.5?"south-west":t>=157.5&&t<=202.5?"west":t>=202.5&&t<=247.5?"north-west":t>=247.5&&t<=292.5?"north":t>=292.5&&t<=337.5?"north-east":"east"})(p)};class mt{#t;#n;startElement;stopElement;firstPathElement;secondPathElement;constructor(t,e){this.#e(t,e)}#e(t,e){if(!t||!e)throw Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw Error("stopElement is not in the DOM");if(!document.body.contains(t))throw Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#n=document.getElementById("ph-speccer-path"),!this.#n||!this.#t)throw Error("Missing required SVG element to draw lines. Please see the documentation");const n=nt();X(this.#t,{height:`${n}px`}),this.connect()}connect(){this.draw(this.#n)}#o(t){if(!t)throw Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${O()}`,n=t.cloneNode(!1),o=this.startElement.getAttribute("id")||O();return this.startElement.setAttribute("id",o),n.setAttribute("data-start-el",o),n.setAttribute("id",e),n.classList.remove("original"),n.classList.add("speccer"),n}async draw(t){if(!t)throw Error("No path given to draw!");const e=this.#o(t),n=this.#o(t);if(!t.parentNode)throw Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(n,t.nextSibling);const o=await gt({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:i,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,n,o,i;switch(t){case"east":e="right-top",n="left-center",o="right-bottom",i="left-center";break;case"south":e="bottom-left",n="top-center",o="bottom-right",i="top-center";break;case"west":e="left-top",n="right-center",o="left-bottom",i="right-center";break;default:e="top-left",n="bottom-center",o="top-right",i="bottom-center"}return{path1pos1:e,path1pos2:n,path2pos1:o,path2pos2:i}})(o),c=await ft(this.startElement,this.stopElement,{pos1:i,pos2:r,firstSet:!0,direction:o}),p=await ft(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:o});this.firstPathElement.setAttribute("data-direction",o),this.firstPathElement.setAttribute("data-pos1",i),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",c),this.secondPathElement.setAttribute("data-direction",o),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",p)}}window.DrawSVGCurlyBracket=mt;class yt{#t;#n;startElement;stopElement;options;line;constructor(t,e,n={}){this.#e(t,e,n)}#e(t,e,n={}){if(!t||!e)throw Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw Error("stopElement is not in the DOM");if(!document.body.contains(t))throw Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.options=n,this.#t=document.getElementById("ph-speccer-svg"),this.#n=document.getElementById("ph-speccer-path"),!this.#n||!this.#t)throw Error("Missing required SVG element to draw lines. Please see the documentation");const o=nt();X(this.#t,{height:`${o}px`}),this.connect()}connect(){this.draw(this.#n)}async draw(t){if(!t)throw Error("No path given to draw!");const e=`ph_draw_path-path-${O()}`,n=t.cloneNode(!1),o=this.startElement.getAttribute("id")||O();this.startElement.setAttribute("id",o),n.setAttribute("id",e),n.setAttribute("data-start-el",o),n.classList.remove("original"),n.classList.add("speccer");const{pin:i}=this.options;if(i?.text&&n.classList.add("text"),!t.parentNode)throw Error("No parentNode found for path");this.line=t.parentNode.insertBefore(n,t.nextSibling);const r=await gt({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:s,pos2:a}=(t=>{let e,n;switch(t){case"east":e="right",n="left";break;case"south":e="bottom",n="top";break;case"west":e="left",n="right";break;default:e="top",n="bottom"}return{pos1:e,pos2:n}})(r),c=await(async(t,e,n)=>{const{pos1:o,pos2:i}=n,{x1:r,y1:s,x2:a,y2:c}=await ht(t,e,o,i),{firstPoint:p,firstControl:l,lastControl:d,lastPoint:h}=ut({x1:r,x2:a,y1:s+document.documentElement.scrollTop,y2:c+document.documentElement.scrollTop},{direction:""});return`M ${p.x} ${p.y}C ${l.x} ${l.y}, ${d.x} ${d.y}, ${h.x} ${h.y}`})(this.startElement,this.stopElement,{pos1:s,pos2:a});this.line.setAttribute("data-direction",r),this.line.setAttribute("data-pos1",s),this.line.setAttribute("data-pos2",a),this.line.setAttribute("d",c)}}window.DrawSVGLine=yt;const wt=t=>parseInt(t,10),bt=t=>wt(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,xt=async(t,e,n,o)=>{await z();const{pin:i={},position:r}=o,{useCurlyBrackets:s,subtle:a,bracket:c,text:p,parent:l,enclose:d}=i,h=bt(e),u=wt(getComputedStyle(e).getPropertyValue("--ph-speccer-measure-size"))||8;const f=await _(e,t);if(d){const{left:t,top:e,height:n,width:o}=f.absolute();return{left:`${t}px`,top:`${e}px`,height:`${n}px`,width:`${o}px`}}if((l||p)&&!c&&!s&&!a){if(r===y.Right){const{top:t}=f.fromRight({center:!0});await z();const{left:e,width:o}=n.getBoundingClientRect();return{left:`${e+o+h}px`,top:`${t}px`}}if(r===y.Bottom){const{left:t}=f.toBottom({center:!0});await z();const{top:e,height:o}=n.getBoundingClientRect();return{left:`${t}px`,top:`${e+o+h}px`}}if(r===y.Left){const{top:t}=f.fromLeft({center:!0});await z();const{left:e}=n.getBoundingClientRect();return{left:e-1.5*h-(p?170:0)+"px",top:`${t}px`}}const{left:t}=f.fromTop({center:!0});await z();const{top:e}=n.getBoundingClientRect();return{left:`${t}px`,top:e-1.5*h+"px"}}if(r===y.Left){if(c&&!s){const{left:t,top:e,height:n}=f.fromLeft({sourceWidth:u});return{left:`${t}px`,top:`${e}px`,height:`${n}px`}}const{left:t,top:e}=f.fromLeft({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(r===y.Right){if(c&&!s){const{left:t,top:e,height:n}=f.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${n}px`}}const{left:t,top:e}=f.fromRight({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(r===y.Bottom){if(c&&!s){const{left:t,top:e,width:n}=f.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${n}px`}}const{left:t,top:e}=f.fromBottom({center:!0,modifier:s?h/1.5:h});return{left:`${t}px`,top:`${e}px`}}if(c&&!s){const{left:t,top:e,width:n}=f.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${n}px`}}const{left:g,top:m}=f.fromTop({center:!0,modifier:s?h/1.5:h});return{left:`${g}px`,top:`${m}px`}},$t=async(t,e,n,o)=>{if(!t)return;if("pin"!==o.type||!o.pin)return;const i=`speccer-${o.slug}-${t.getAttribute("id")||O()}`,r=et(n,o,i);t.setAttribute("data-speccer-element-id",i),document.body.appendChild(r);const s=await xt(t,r,e,o);await X(r,s);const a=o.pin.text&&null!==t.getAttribute("data-speccer-title"),c=o.pin.parent&&!o.pin.enclose&&!o.pin.bracket&&!a;return o.pin.useSVGLine?(new yt(t,r,o),c&&new dt(t,5,o)):o.pin.useCurlyBrackets&&new mt(t,r),i};let Et=0;const At=async(t,e)=>{if(!t)return;const n=t.querySelectorAll('[data-speccer^="pin"]');if(!n||0===n.length)return;const o=t.getAttribute("data-speccer-literals")||window.SPECCER_LITERALS||c;[...n].filter((async t=>!V(t))).forEach((async(n,i)=>{const r=((t,e)=>{let n=e[t];return 0===t&&(Et=0),n||(n=`${e[Et]}${e[Et].toLowerCase()}`,Et++),n})(i,o),s=n.getAttribute("data-speccer")||"";await z();const a=getComputedStyle(n),c=I(s,a,e),p=((t,e,n)=>{const{pin:o}=n;if(!o)return t;const{text:i}=o;if(!i||null===e.getAttribute("data-speccer-title"))return t;const r=e.getAttribute("data-speccer-title"),s=e.getAttribute("data-speccer-description"),a=0===e.nodeName.indexOf("H")?`<span class="ph-speccer heading">${e.nodeName}</span>`:"";return!s&&r?`${a}<span class="ph-speccer title">${r}</span>`:s&&r?`${a}<span class="ph-speccer title">${r}</span><span class="ph-speccer description">${s.replaceAll("\\n","<br/>")}</span>`:t})(r,n,c);await $t(n,t,p,c)}))},St=(t="",e="span")=>{const n=document.createElement(e),o=document.createTextNode(`${t}px`);return n.appendChild(o),n.setAttribute("title",`${t}px`),s(n,"ph-speccer speccer spacing"),n},Ct=async(t,e)=>{if(!t)return;if(V(t))return;const n=t.getAttribute("data-speccer")||"",o=await Y(t),i=I(n,o,e);if("spacing"!==i.type||!i.spacing)return;const r=((t,e)=>{const{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r,paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}=t;return e?.spacing?.padding?{paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}:e?.spacing?.margin?{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r}:{marginTop:n,marginBottom:o,marginLeft:i,marginRight:r,paddingTop:s,paddingBottom:a,paddingLeft:c,paddingRight:p}})(o,i),c=Object.keys(r).filter((t=>"0px"!==r[t]));if(!c.length)return;t.classList.add("is-specced");const p=`speccer-spacing-${t.getAttribute("id")||O()}`;t.setAttribute("data-speccer-element-id",p),c.forEach((async e=>{const n=wt(r[e]),o=St(n);o.setAttribute("data-speccer-id",p);const c=(t=>t.includes("Top")?t.replace("Top"," top"):t.includes("Right")?t.replace("Right"," right"):t.includes("Bottom")?t.replace("Bottom"," bottom"):t.includes("Left")?t.replace("Left"," left"):"")(e);s(o,a(c,{bound:!!i?.spacing?.bound})),document.body.appendChild(o);const l=await(async(t,e,n,o)=>{await z();const i=n.getBoundingClientRect(),r=await F(n),s=o?.spacing?.bound?0:96,a=o?.spacing?.bound?0:48;return"marginTop"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top-e+"px"}:"marginRight"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+parseInt(i.width+"",10)+"px",top:r.top+"px"}:"marginBottom"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+parseInt(i.height+"",10)+"px"}:"marginLeft"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}:"paddingTop"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+"px"}:"paddingBottom"===t?{height:`${e}px`,width:i.width+s+"px",left:r.left-s+"px",top:r.top+(parseInt(i.height+"",10)-e)+"px"}:"paddingRight"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+(parseInt(i.width+"",10)-e)+"px",top:r.top+"px"}:"paddingLeft"===t?{height:i.height+a+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"}:void 0})(e,n,t,i);await X(o,l)}))},kt=(t,e=3)=>parseFloat(String(t)).toFixed(e),vt=(t,e,n)=>{const o=document.createElement("div"),{typography:i,position:r}=e,c=a("ph-speccer speccer typography",{syntax:i?.useSyntaxHighlighting||!1,[r]:!0});return o.setAttribute("id",n),o.setAttribute("data-speccer-id",n),o.innerHTML=t,s(o,c),o},Pt=async(t,e)=>{if(!t)return;if(V(t))return;const n=t.getAttribute("data-speccer")||"";await z();const o=I(n,getComputedStyle(t),e);if("typography"!==o.type||!o.typography)return;t.classList.add("is-specced");const i=await(async(t,e=!1)=>{const n=(t=>{const{lineHeight:e,letterSpacing:n,fontFamily:o,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:n,fontFamily:o,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await Y(t));if(e){const t=(n.fontFamily||"").split(",").map((t=>t.includes('"\'"')?`<span class="token string">${t}</span>`:t)).join('<span class="token punctuation">, </span>'),e=`<span class="token number">${parseInt(n.fontSize||"NaN",10)}</span><span class="token unit">px</span> <span class="token operator">/</span> <span class="token number">${parseInt(n.fontSize||"NaN",10)/16}</span><span class="token unit">rem</span>`,o=n.letterSpacing?n.letterSpacing.includes("px")?`<span class="token number">${parseInt(n.letterSpacing,10)}</span><span class="token unit">px</span>`:n.letterSpacing:"",i=n.lineHeight?"normal"!==n.lineHeight?`<span class="token number">${parseInt(n.lineHeight,10)}</span><span class="token unit">px</span> <span class="token operator">/</span> <span class="token number">${parseInt(n.lineHeight,10)/16}</span><span class="token unit">rem</span>`:"normal":"";return`\n<pre class="language-css" tabindex="-1"><code class="language-css"><span class="token selector"><span class="token class">.typography</span></span> <span class="token punctuation">{</span>\n <span class="token property">font-family</span><span class="token punctuation">:</span> ${t}<span class="token punctuation">;</span>\n <span class="token property">font-size</span><span class="token punctuation">:</span> ${e}<span class="token punctuation">;</span>\n <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">${n.fontWeight}</span><span class="token punctuation">;</span>\n <span class="token property">font-variation-settings</span><span class="token punctuation">:</span> ${n.fontVariationSettings}<span class="token punctuation">;</span>\n <span class="token property">line-height</span><span class="token punctuation">:</span> ${i}<span class="token punctuation">;</span>\n <span class="token property">letter-spacing</span><span class="token punctuation">:</span> ${o}<span class="token punctuation">;</span>\n <span class="token property">font-style</span><span class="token punctuation">:</span> ${n.fontStyle}<span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre>`}return`\ntypography: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${n.fontFamily};</li> <li><span class="property">font-size:</span> ${n.fontSize} / ${parseInt(n.fontSize||"NaN",10)/16}rem;</li> <li><span class="property">font-weight:</span> ${n.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${n.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${"normal"!==n.lineHeight?`${parseInt(n.lineHeight||"NaN",10)}px / ${parseInt(n.lineHeight||"NaN",10)/16}rem`:"normal"};</li> <li><span class="property">letter-spacing:</span> ${n.letterSpacing};</li> <li><span class="property">font-style:</span> ${n.fontStyle};</li></ul>}`})(t,o.typography.useSyntaxHighlighting),r=`speccer-${o.slug}-${t.getAttribute("id")||O()}`;t.setAttribute("data-speccer-element-id",r);const s=vt(i,o,r);document.body.appendChild(s);const a=await(async(t,e,n)=>{const o=e.getBoundingClientRect(),i=bt(n),r=n.getBoundingClientRect(),s=await F(e),{typography:a,position:c}=t;if(a&&c===b.Right)return{left:s.left+o.width+i+"px",top:kt(D(s.top,r,o))+"px"};if(a&&c===b.Top)return{left:kt(W(s.left,r,o))+"px",top:s.top-r.height-i+"px"};if(a&&c===b.Bottom)return{left:kt(W(s.left,r,o))+"px",top:s.top+o.height+i+"px"};return{left:s.left-r.width-i+"px",top:kt(D(s.top,r,o))+"px"}})(o,t,s);X(s,a)},Lt=t=>{const e=()=>((t,e,n=!1)=>{let o;return function(i,...r){const s=n&&!o;o&&clearTimeout(o),o=setTimeout((function(){o=null,n||t.apply(i,r)}),e),s&&t.apply(i,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},Bt=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},Rt=()=>{const t=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(Ct(n.target),e.unobserve(n.target))}));for(const e of document.querySelectorAll(`[${p}^="${l}"],[${p}^="${l}"] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)`))t.observe(e);const e=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(tt(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${p}^="${d}"]`))e.observe(t);const n=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(J(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${p}^="${u}"]`))n.observe(t);const o=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(Pt(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${p}^="${h}"]`))o.observe(t);const i=new IntersectionObserver(((t,e)=>{for(const n of t)n.intersectionRatio>0&&(U(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${p}^="${f}"]`))i.observe(t);const r=new IntersectionObserver((async(t,e)=>{for(const n of t)n.intersectionRatio>0&&(await At(n.target),e.unobserve(n.target))}));for(const t of document.querySelectorAll(`[${p}="${g}"]`))r.observe(t)},Tt=t=>{window.speccer=t},Nt=t=>{const e=document.currentScript;if(e){const n=e.getAttribute("src");n?.includes("speccer.js")&&(e.hasAttribute("data-manual")?Tt(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?Bt(t):e.hasAttribute("data-lazy")?Rt():Bt(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||Lt(t))}},qt=["alt","altgraph","capslock","control","fn","fnlock","hyper","meta","numlock","os","scrolllock","shift","super","symbol","command","ctrl","altgr","symbollock"],Mt=["escape","esc","enter","return","⏎","␛"],Ht=async(t,e,n)=>{await z();const o=bt(n),i=await _(n,e);if("tabstops"===t){let{left:t,top:e}=i.fromTop();return t-=32,e+=32,t<=0&&(t=32),e<=0&&(e=32),{left:`${t}px`,top:`${e}px`}}if("landmark"===t||"autocomplete"===t||"headings"===t){let{left:t,top:e}=i.fromLeft();return t-=o,t<=0&&(t=o),e<=0&&(e=o),{left:`${t}px`,top:`${e}px`}}if("region"===t){const{left:t,top:e,height:n,width:o}=i.fromTop();return{height:`${n}px`,width:`${o}px`,left:`${t}px`,top:`${e}px`}}if("shortcut"===t){const{left:t,top:e}=i.fromBottom();return{left:`${t}px`,top:`${e}px`}}const{left:r,top:s}=i.fromTop({center:!0,modifier:o});return{left:r-32+"px",top:s-32+"px"}},It=async(t,e,n)=>{if(!t||!t.checkVisibility())return;const o=((t="tabstops",e,n="span")=>{const o=document.createElement(n),i=a("ph-speccer speccer a11y",{tabstops:"tabstops"===t,landmark:"landmark"===t,autocomplete:"autocomplete"===t,headings:"headings"===t,region:"region"===t});if("landmark"===t&&e){const t=document.createTextNode(String(e));o.appendChild(t)}return s(o,i),o})(n,e);if("landmark"===n){const e=(t=>{if(!t)return"";if(t.role&&""!==t.role)return t.role;const e=t.nodeName.toLowerCase();return["header","footer","section","form","main","nav","aside"].includes(e)?e:"N/A"})(t),n=t.nodeName.toLowerCase();o.innerHTML=`&lt;${n} role="${e}"&gt;`}if("autocomplete"===n){const e=t.getAttribute("autocomplete")||"";o.innerHTML=`autocomplete="${e}"`}"headings"===n&&(o.innerHTML=t.nodeName,o.classList.add(t.nodeName.toLowerCase())),"tabstops"===n&&o.setAttribute("data-speccer-a11y-tabstops",e);const i=`speccer-a11y-${t.getAttribute("id")||O()}`;o.setAttribute("data-speccer-id",i),document.body.appendChild(o);const r=await Ht(n,t,o);await X(o,r)},Ot=async(t,e)=>{const n=e.split(/\s\+\s/).map((t=>t.trim())),o=document.createElement("div"),i=a("ph-speccer speccer a11y shortcut-holder");s(o,i);for(const t of n){const e=document.createElement("kbd"),n=document.createTextNode(t),i=a("ph-speccer speccer a11y shortcut",{modifier:qt.includes(t.toLowerCase()),physical:Mt.includes(t.toLowerCase())});s(e,i),e.appendChild(n);const r=`speccer-a11y-shortcut-${O()}`;o.setAttribute("data-speccer-id",r),o.appendChild(e)}document.body.appendChild(o);const r=await Ht("shortcut",t,o);await X(o,r)},Vt={create:K,element:U},zt={create:St,element:Ct},Gt={createPinElement:et,pinElement:$t,pinElements:At},jt={create:Q,element:tt},Wt={create:Z,element:J},Dt={create:vt,element:Pt},Ft={dom:Bt,lazy:Rt,manual:Tt,activate:Nt},_t=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".ph-speccer.speccer");const t=document.querySelectorAll(`[${p}^="${l}"]`),e=document.querySelectorAll(`[${p}^="${d}"]`),n=document.querySelectorAll(`[${p}^="${h}"]`),o=document.querySelectorAll(`[${p}="${g}"]`),i=document.querySelectorAll(`[${p}^="${u}"]`),r=document.querySelectorAll(`[${p}^="${f}"]`);for(const t of i)J(t);for(const t of r)U(t);for(const e of t)if(Ct(e),e.hasChildNodes()){const t=e.querySelectorAll("*:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody):not([data-speccer])"),n=e.getAttribute("data-speccer")||"";if(t?.length)for(const e of t)e.setAttribute("data-speccer",n),Ct(e)}for(const t of e)tt(t);for(const t of n)Pt(t);for(const t of o)At(t);(()=>{const t=document.querySelectorAll('[data-speccer*="a11y tabstops"]'),e=document.querySelectorAll('[data-speccer*="a11y landmark"]'),n=document.querySelectorAll('[data-speccer*="a11y shortcut"]'),o=document.querySelectorAll('[data-speccer*="a11y autocomplete"]'),i=document.querySelectorAll('[data-speccer*="a11y headings"]');if(n.length)for(const t of n){const e=t.getAttribute("data-speccer-a11y-shortcut");e&&""!==e&&!V(t)&&Ot(t,e)}if(t.length)for(const e of t){const t=e.querySelectorAll("\n a[href], area[href], input:not([disabled]):not([tabindex='-1']),\n button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']),\n textarea:not([disabled]):not([tabindex='-1']),\n iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]\n");for(const[e,n]of t.entries()){if(!V(n)){It(n,e+1,"tabstops");continue}const t=n.getAttribute("id");if(!t)continue;const o=document.querySelector(`[for="${t}"]`);o&&!V(o)&&It(o,e+1,"tabstops")}}if(o.length)for(const t of o){const e=t.querySelectorAll("[autocomplete]");for(const t of e)V(t)||It(t,null,"autocomplete")}if(i.length)for(const t of i){const e=t.querySelectorAll('h1,h2,h3,h4,h5,h6, [role="heading"]');for(const t of e)V(t)||It(t,null,"headings")}if(e.length)for(const t of e){const e=t.querySelectorAll('\nheader, footer, section, form, main, nav, aside, [role="section"], [role="banner"],\n[role="complementary"], [role="contentinfo"], [role="form"], [role="main"],\n[role="navigation"], [role="region"], [role="search"]\n');for(const[t,n]of e.entries())V(n)||(It(n,t+1,"landmark"),It(n,null,"region"))}})()};Nt(_t),t.default=_t,t.grid=Vt,t.mark=Wt,t.measure=jt,t.modes=Ft,t.pin=Gt,t.removeSpeccerElement=t=>{const e=t.getAttribute("data-speccer-element-id");if(!e)return;const n=document.getElementById(e)||document.querySelectorAll(`[data-speccer-id="${e}"]`);if(n)if(Object.prototype.isPrototypeOf.call(NodeList.prototype,n))[...n].forEach((t=>{t.remove(),t.classList.remove("is-specced")}));else if(n.classList.contains("curly")||n.classList.contains("svg")){const e=t.getAttribute("id");document.querySelectorAll(`#ph-speccer-svg path[data-start-el="${e}"]`).forEach((t=>t.remove()))}},t.spacing=zt,t.typography=Dt,Object.defineProperty(t,"__esModule",{value:!0})}));
28
- //# sourceMappingURL=speccer.js.map
package/package.json CHANGED
@@ -1,85 +1,86 @@
1
1
  {
2
2
  "name": "@phun-ky/speccer",
3
- "version": "11.2.8",
3
+ "version": "11.2.10",
4
4
  "description": "A script to annotate, show spacing specs and to display typography information in documentation/website on HTML elements",
5
- "main": "dist/speccer.js",
6
- "module": "dist/speccer.esm.js",
7
- "types": "dist/speccer.d.ts",
8
- "funding": "https://github.com/phun-ky/speccer?sponsor=1",
9
- "type": "module",
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "scripts": {
14
- "test": "npm run test:unit",
15
- "test:unit": "glob -c \"node --import tsx --import global-jsdom/register --test --no-warnings\" \"./src/**/__tests__/**/*.spec.[jt]s\"",
16
- "pretest:ci": "rm -rf coverage && mkdir -p coverage",
17
- "test:ci": "glob -c \"node --import tsx --import global-jsdom/register --test --no-warnings --experimental-test-coverage --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"./src/**/__tests__/**/*.spec.[jt]s\"",
18
- "pretest:e2e": "rm -rf test-results && npm run build",
19
- "test:e2e": "npx playwright test",
20
- "rollup": "rollup -c",
21
- "prerollup:dev": "npm run clean && npm run styles",
22
- "rollup:dev": "rollup -c -w",
23
- "clean": "rm -rf dist dts",
24
- "build": "npm run clean && npm run rollup && npm run styles",
25
- "styles": "npm run stylus && npm run postcss",
26
- "stylus": "rm -rf ./dist/speccer.css && stylus ./src/styles/index.styl -o ./dist/speccer.css",
27
- "postcss": "rm -rf ./dist/speccer.min.css && postcss ./dist/speccer.css -o ./dist/speccer.min.css",
28
- "dev": "npx browser-sync start --server 'dev' --files 'dist' --ss 'dist'",
29
- "docs:gen": "node ./node_modules/.bin/typedoc",
30
- "style:lint": "./node_modules/.bin/eslint -c ./eslint.config.mjs src",
31
- "style:format": "./node_modules/.bin/eslint -c ./eslint.config.mjs src --fix",
32
- "style:code": "npx putout src",
33
- "commit": "npx git-cz",
34
- "release": "release-it"
35
- },
36
- "files": [
37
- "/dist/speccer.esm.js",
38
- "/dist/speccer.esm.js.map",
39
- "/dist/speccer.js",
40
- "/dist/speccer.js.map",
41
- "/dist/speccer.min.css",
42
- "/dist/speccer.css",
43
- "/dist/speccer.d.ts"
44
- ],
45
- "repository": {
46
- "type": "git",
47
- "url": "git+https://github.com/phun-ky/speccer.git"
48
- },
49
5
  "keywords": [
50
- "html",
6
+ "a11y",
7
+ "accessibility",
8
+ "anatomy",
9
+ "annotate",
10
+ "annotation",
51
11
  "css",
52
12
  "design",
53
13
  "design system",
54
- "javascript",
55
- "spec",
56
- "inspect",
57
- "annotation",
58
- "annotate",
59
- "pin",
60
- "specifications",
61
- "anatomy",
62
- "dissection",
63
14
  "dissect",
15
+ "dissection",
64
16
  "documentation",
65
- "information",
66
- "specification",
67
- "specs",
17
+ "grid",
18
+ "grid-layout",
19
+ "html",
68
20
  "html-elements",
21
+ "information",
69
22
  "inspect",
23
+ "javascript",
24
+ "pin",
70
25
  "spacing",
26
+ "spec",
71
27
  "speccer",
72
- "a11y",
73
- "accessibility",
74
- "grid",
75
- "grid-layout"
28
+ "specification",
29
+ "specifications",
30
+ "specs",
31
+ "typescript",
32
+ "typography"
76
33
  ],
77
- "author": "Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>",
78
- "license": "MIT",
34
+ "homepage": "https://phun-ky.net/projects/speccer",
79
35
  "bugs": {
80
36
  "url": "https://github.com/phun-ky/speccer/issues"
81
37
  },
82
- "homepage": "https://phun-ky.net/projects/speccer",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/phun-ky/speccer.git"
41
+ },
42
+ "funding": "https://github.com/phun-ky/speccer?sponsor=1",
43
+ "license": "MIT",
44
+ "author": "Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>",
45
+ "type": "module",
46
+ "main": "dist/speccer.js",
47
+ "module": "dist/speccer.esm.js",
48
+ "types": "dist/speccer.d.ts",
49
+ "files": [
50
+ "/dist/speccer.css",
51
+ "/dist/speccer.d.ts",
52
+ "/dist/speccer.esm.js",
53
+ "/dist/speccer.js",
54
+ "/dist/speccer.min.css"
55
+ ],
56
+ "scripts": {
57
+ "build": "npm run clean && npm run rollup && npm run styles",
58
+ "clean": "rm -rf dist dts",
59
+ "commit": "npx git-cz",
60
+ "dev": "npx browser-sync start --server 'dev' --files 'dist' --ss 'dist'",
61
+ "docs:gen": "node ./node_modules/.bin/typedoc",
62
+ "postcss": "rm -rf ./dist/speccer.min.css && postcss ./dist/speccer.css -o ./dist/speccer.min.css",
63
+ "release": "release-it",
64
+ "prerollup:dev": "npm run clean && npm run styles",
65
+ "rollup": "rollup -c",
66
+ "rollup:dev": "rollup -c -w",
67
+ "style:code": "npx putout src",
68
+ "style:format": "./node_modules/.bin/eslint -c ./eslint.config.mjs src --fix && ./node_modules/.bin/prettier --write ./eslint.config.mjs src",
69
+ "style:lint": "./node_modules/.bin/eslint -c ./eslint.config.mjs src && ./node_modules/.bin/prettier --check src",
70
+ "styles": "npm run stylus && npm run postcss",
71
+ "stylus": "rm -rf ./dist/speccer.css && stylus ./src/styles/index.styl -o ./dist/speccer.css",
72
+ "pretest:ci": "rm -rf coverage && mkdir -p coverage",
73
+ "pretest:e2e": "rm -rf test-results && npm run build",
74
+ "test": "npm run test:unit",
75
+ "test:ci": "glob -c \"node --import tsx --import global-jsdom/register --test --no-warnings --experimental-test-coverage --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"./src/**/__tests__/**/*.spec.[jt]s\"",
76
+ "test:e2e": "npx playwright test",
77
+ "test:unit": "glob -c \"node --import tsx --import global-jsdom/register --test --no-warnings\" \"./src/**/__tests__/**/*.spec.[jt]s\""
78
+ },
79
+ "config": {
80
+ "commitizen": {
81
+ "path": "./node_modules/git-cz"
82
+ }
83
+ },
83
84
  "devDependencies": {
84
85
  "@eslint/js": "^9.20.0",
85
86
  "@playwright/test": "^1.50.1",
@@ -87,11 +88,11 @@
87
88
  "@rollup/plugin-node-resolve": "^16.0.0",
88
89
  "@rollup/plugin-terser": "^0.4.4",
89
90
  "@stylistic/eslint-plugin": "^3.1.0",
90
- "@testing-library/dom": "^9.3.4",
91
+ "@testing-library/dom": "^10.4.0",
91
92
  "@testing-library/jest-dom": "^6.4.2",
92
93
  "@types/node": "^22.13.1",
93
94
  "cobertura": "^1.0.1",
94
- "cssnano": "^6.0.3",
95
+ "cssnano": "^7.0.6",
95
96
  "eslint": "^9.20.0",
96
97
  "eslint-config-prettier": "^10.0.1",
97
98
  "eslint-import-resolver-typescript": "^3.7.0",
@@ -99,13 +100,13 @@
99
100
  "eslint-plugin-import": "^2.31.0",
100
101
  "eslint-plugin-prettier": "^5.2.3",
101
102
  "git-cz": "^4.9.0",
102
- "glob": "^10.3.10",
103
+ "glob": "^11.0.1",
103
104
  "global-jsdom": "^26.0.0",
104
105
  "globals": "^15.14.0",
105
106
  "jsdom": "^26.0.0",
106
- "postcss": "^8.3.0",
107
- "postcss-cli": "^8.3.1",
108
- "prettier": "3.5.0",
107
+ "postcss": "^8.5.2",
108
+ "postcss-cli": "^11.0.0",
109
+ "prettier": "3.5.1",
109
110
  "putout": "^38.2.0",
110
111
  "quibble": "^0.9.1",
111
112
  "release-it": "^18.1.2",
@@ -117,7 +118,7 @@
117
118
  "stylus": "^0.64.0",
118
119
  "ts-node": "^10.9.1",
119
120
  "tslib": "^2.3.1",
120
- "tsx": "^4.7.1",
121
+ "tsx": "^4.19.2",
121
122
  "typedoc": "^0.27.6",
122
123
  "typedoc-plugin-frontmatter": "^1.0.0",
123
124
  "typedoc-plugin-markdown": "^4.2.3",
@@ -129,13 +130,11 @@
129
130
  "typescript-eslint": "^8.23.0",
130
131
  "unified-prettier": "^2.0.1"
131
132
  },
132
- "config": {
133
- "commitizen": {
134
- "path": "./node_modules/git-cz"
135
- }
136
- },
137
133
  "engines": {
138
134
  "node": ">=22.9.0",
139
135
  "npm": ">=11.0.0"
136
+ },
137
+ "publishConfig": {
138
+ "access": "public"
140
139
  }
141
140
  }