@phun-ky/speccer 6.4.0 → 8.0.0
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 +36 -24
- package/package.json +10 -2
- package/speccer.d.ts +52 -0
- package/speccer.js +1 -1
- package/speccer.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,42 +1,54 @@
|
|
|
1
1
|
# @phun-ky/speccer
|
|
2
2
|
|
|
3
|
-

|
|
4
|
+
|
|
5
|
+
> A zero dependency package to highlight elements
|
|
4
6
|
|
|
5
7
|
[](http://commitizen.github.io/cz-cli/) [](http://makeapullrequest.com) [](http://semver.org/spec/v2.0.0.html)      
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
1. [@phun-ky/speccer](#phun-kyspeccer)
|
|
12
|
+
1. [About](#about)
|
|
13
|
+
2. [API](#api)
|
|
14
|
+
3. [Usage](#usage)
|
|
15
|
+
1. [Typescript](#typescript)
|
|
16
|
+
2. [ESM](#esm)
|
|
17
|
+
3. [Script](#script)
|
|
18
|
+
4. [React](#react)
|
|
19
|
+
4. [Advanced usage](#advanced-usage)
|
|
20
|
+
1. [Lazy](#lazy)
|
|
21
|
+
5. [Features](#features)
|
|
22
|
+
1. [Element spacing](#element-spacing)
|
|
23
|
+
2. [Element dimensions](#element-dimensions)
|
|
24
|
+
1. [Subtle measure](#subtle-measure)
|
|
25
|
+
3. [Highlight the anatomy of an element](#highlight-the-anatomy-of-an-element)
|
|
26
|
+
1. [Subtle anatomy](#subtle-anatomy)
|
|
27
|
+
4. [Curly brackets](#curly-brackets)
|
|
28
|
+
5. [Element typography](#element-typography)
|
|
29
|
+
6. [Mark elements](#mark-elements)
|
|
30
|
+
6. [Customization](#customization)
|
|
27
31
|
|
|
28
32
|
## About
|
|
29
33
|
|
|
30
|
-
Speccer was created to make it easier to document components in a design system
|
|
34
|
+
Speccer was originally created to make it easier to document components in a design system, but you can use it to whatever you like, if you are in the need to highlight any element!
|
|
31
35
|
|
|
32
|
-
```
|
|
36
|
+
```shell-session
|
|
33
37
|
npm i @phun-ky/speccer
|
|
34
38
|
```
|
|
35
39
|
|
|
36
40
|
See demo here: <https://codepen.io/phun-ky/pen/xaOrYX>
|
|
37
41
|
|
|
42
|
+
## API
|
|
43
|
+
|
|
44
|
+
Go [here](https://github.com/phun-ky/speccer/blob/main/api/README.md) to read the full API documentation.
|
|
45
|
+
|
|
38
46
|
## Usage
|
|
39
47
|
|
|
48
|
+
### Typescript
|
|
49
|
+
|
|
50
|
+
Types can be found in `@phun-ky/speccer/speccer.d.ts`.
|
|
51
|
+
|
|
40
52
|
### ESM
|
|
41
53
|
|
|
42
54
|
Either import and run the required functions:
|
|
@@ -232,7 +244,7 @@ The curly brackets are made with SVG paths, and it is required to have the follo
|
|
|
232
244
|
|
|
233
245
|
This will give a dashed border, and a more subtle pin style.
|
|
234
246
|
|
|
235
|
-
### Element
|
|
247
|
+
### Element typography
|
|
236
248
|
|
|
237
249
|

|
|
238
250
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phun-ky/speccer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "A script to annotate, show spacing specs and to display typography information in documentation/website on HTML elements",
|
|
5
5
|
"main": "speccer.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"stylus": "rm -rf ./speccer.css && stylus ./src/styles/index.styl -o ./speccer.css",
|
|
18
18
|
"postcss": "rm -rf ./speccer.min.css && postcss ./speccer.css -o speccer.min.css",
|
|
19
19
|
"dev": "npx browser-sync start --server --files \"dev/*.html\" \"*.css\" --index \"dev/index.html\" --serveStatic \"/dev/*.html\"",
|
|
20
|
+
"docs:gen": "node ./node_modules/.bin/typedoc --entryPoints src --entryPointStrategy expand --gitRevision main --githubPages false --plugin typedoc-plugin-markdown --tsconfig tsconfig.json --hideInPageTOC --out api --readme none",
|
|
20
21
|
"commit": "npx git-cz",
|
|
21
22
|
"release": "release-it"
|
|
22
23
|
},
|
|
@@ -24,7 +25,8 @@
|
|
|
24
25
|
"/speccer.js",
|
|
25
26
|
"/speccer.js.map",
|
|
26
27
|
"/speccer.min.css",
|
|
27
|
-
"/speccer.css"
|
|
28
|
+
"/speccer.css",
|
|
29
|
+
"/speccer.d.ts"
|
|
28
30
|
],
|
|
29
31
|
"repository": {
|
|
30
32
|
"type": "git",
|
|
@@ -93,6 +95,12 @@
|
|
|
93
95
|
"rollup-plugin-typescript2": "^0.35.0",
|
|
94
96
|
"stylus": "^0.60.0",
|
|
95
97
|
"tslib": "^2.3.1",
|
|
98
|
+
"typedoc": "^0.25.2",
|
|
99
|
+
"typedoc-plugin-frontmatter": "^0.0.2",
|
|
100
|
+
"typedoc-plugin-markdown": "^3.15.3",
|
|
101
|
+
"typedoc-plugin-mdn-links": "^3.0.3",
|
|
102
|
+
"typedoc-plugin-no-inherit": "^1.4.0",
|
|
103
|
+
"typedoc-plugin-rename-defaults": "^0.6.5",
|
|
96
104
|
"typescript": "^4.5.4"
|
|
97
105
|
},
|
|
98
106
|
"config": {
|
package/speccer.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
declare type SpeccerFunctionType = () => void;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extends the global Window interface to add custom properties.
|
|
5
|
+
*/
|
|
6
|
+
declare global {
|
|
7
|
+
interface Window {
|
|
8
|
+
/**
|
|
9
|
+
* Represents the DrawSVGCurlyBracket class for drawing curly brackets.
|
|
10
|
+
*/
|
|
11
|
+
DrawSVGCurlyBracket: any;
|
|
12
|
+
/**
|
|
13
|
+
* Represents the DrawSVGLine class for drawing lines.
|
|
14
|
+
*/
|
|
15
|
+
DrawSVGLine: any;
|
|
16
|
+
/**
|
|
17
|
+
* Represents the speccer object for additional functionality.
|
|
18
|
+
*/
|
|
19
|
+
speccer: any;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=global.d.ts.map
|
|
23
|
+
|
|
24
|
+
declare const spacing: {
|
|
25
|
+
create: (text?: string | number, tag?: string) => HTMLElement;
|
|
26
|
+
element: (targetEl: HTMLElement) => Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
declare const dissect: {
|
|
29
|
+
create: (textContent: string | undefined, area: string, n?: string) => HTMLElement;
|
|
30
|
+
element: (sectionEl: HTMLElement) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
declare const measure: {
|
|
33
|
+
create: (text?: string | number, area?: string | null, tag?: string) => HTMLElement;
|
|
34
|
+
element: (targetEl: HTMLElement) => Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
declare const mark: {
|
|
37
|
+
create: (n?: string) => HTMLElement;
|
|
38
|
+
element: (elementToMark: HTMLElement) => Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
declare const typography: {
|
|
41
|
+
create: (html: string, area: string | null) => HTMLElement;
|
|
42
|
+
element: (targetEl: HTMLElement) => Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
declare const modes: {
|
|
45
|
+
dom: (speccer: SpeccerFunctionType) => void;
|
|
46
|
+
lazy: () => void;
|
|
47
|
+
manual: (speccer: SpeccerFunctionType) => void;
|
|
48
|
+
activate: (speccer: SpeccerFunctionType) => void;
|
|
49
|
+
};
|
|
50
|
+
declare const speccer: () => void;
|
|
51
|
+
|
|
52
|
+
export { speccer as default, dissect, mark, measure, modes, spacing, typography };
|
package/speccer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!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,e,o="noop")=>{t&&(!e||e&&0===e.length||e.trim().split(" ").filter((t=>t!==o)).forEach((e=>t.classList.add(e))))},o=(t,e)=>t?e||"string"==typeof t?`${t} ${e?Object.keys(e).filter((t=>e[t])).join(" "):""}`.trim():`${Object.keys(t).filter((e=>t[e])).join(" ")}`.trim():"",n=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],i=t=>parseInt(t,10),r=t=>i(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,s=()=>new Promise(requestAnimationFrame),a=async(t,e)=>{!t||!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e||Array.isArray(e)&&0===e.length||0===Object.keys(e).length&&e.constructor===Object||(await s(),Array.isArray(e)?e.forEach((e=>t.style[e.key]=e.value)):Object.keys(e).forEach((o=>t.style[o]=e[o])))},p=async t=>(await s(),getComputedStyle(t,null)),c=(t,e,o)=>t-e.width/2+o.width/2,l=(t,e,o)=>t-e.height/2+o.height/2,h=async t=>{await s();const e=t.getBoundingClientRect(),o=e.top+window.pageYOffset,n=e.left+window.pageXOffset;return{height:e.height,width:e.width,top:o,left:n}},d=async(t,e)=>{await s();const o=t.getBoundingClientRect(),n=await h(e),i=await(async(t,e)=>{await s();const o=t.getBoundingClientRect(),n=e.getBoundingClientRect(),i=n.top+window.pageYOffset,r=n.left+window.pageXOffset;return{height:n.height,width:n.width,top:l(i,o,n),left:c(r,o,n)}})(t,e),r=n.height,a=n.width,p=o.height,d=o.width;return{absolute:()=>({top:n.top,left:n.left,height:r,width:a}),toTop:({center:t=!1,sourceHeight:e=p,modifier:o=0}={})=>({top:n.top+e+o,left:t?i.left:n.left,height:r,width:a}),fromTop:({center:t=!1,sourceHeight:e=p,modifier:o=0}={})=>({top:n.top-e-o,left:t?i.left:n.left,height:r,width:a}),toBottom:({center:t=!1,sourceHeight:e=p,targetHeight:o=r,modifier:s=0}={})=>({top:n.top+o-(e+s),left:t?i.left:n.left,height:r,width:a}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:o=0}={})=>({top:n.top+e+o,left:t?i.left:n.left,height:r,width:a}),toLeft:({center:t=!1,sourceWidth:e=d,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left+e+o,height:r,width:a}),fromLeft:({center:t=!1,sourceWidth:e=d,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left-e-o,height:r,width:a}),toRight:({center:t=!1,sourceWidth:e=d,targetWidth:o=a,modifier:s=0}={})=>({top:t?i.top:n.top,left:n.left+o-(e+s),height:r,width:a}),fromRight:({center:t=!1,targetWidth:e=a,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left+e+o,height:r,width:a})}},f=(t="",o="span")=>{const n=document.createElement(o),i=document.createTextNode(t+"");return n.appendChild(i),n.setAttribute("title",t+"px"),e(n,"ph speccer spacing"),n},u=async t=>{if(!t)return;const o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;const n=(t=>{const{marginTop:e,marginBottom:o,marginLeft:n,marginRight:i,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}=t;return{marginTop:e,marginBottom:o,marginLeft:n,marginRight:i,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}})(o),r=Object.keys(n).filter((t=>"0px"!==n[t]));0!==r.length&&r.forEach((async o=>{const r=i(n[o]),p=f(r),c=(t=>-1!==t.indexOf("Top")?t.replace("Top"," top"):-1!==t.indexOf("Right")?t.replace("Right"," right"):-1!==t.indexOf("Bottom")?t.replace("Bottom"," bottom"):-1!==t.indexOf("Left")?t.replace("Left"," left"):"")(o);e(p,c),document.body.appendChild(p),t.classList.add("is-specced"),await(async(t,e,o,n)=>{await s();const i=n.getBoundingClientRect(),r=await h(n);"marginTop"===t&&a(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top-e+"px"}),"marginRight"===t&&a(o,{height:i.height+"px",width:`${e}px`,left:r.left+parseInt(i.width+"",10)+"px",top:r.top+"px"}),"marginBottom"===t&&a(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+parseInt(i.height+"",10)+"px"}),"marginLeft"===t&&a(o,{height:i.height+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}),"paddingTop"===t&&a(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+"px"}),"paddingBottom"===t&&a(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+(parseInt(i.height+"",10)-e)+"px"}),"paddingRight"===t&&a(o,{height:i.height+"px",width:`${e}px`,left:r.left+(parseInt(i.width+"",10)-e)+"px",top:r.top+"px"}),"paddingLeft"===t&&a(o,{height:i.height+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"})})(o,r,p,t)}))};var m,g,w,y=Object.freeze({__proto__:null,create:f,element:u});!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(m||(m={})),function(t){t.Outline="outline",t.Enclose="enclose",t.Full="full",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(g||(g={})),function(t){t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(w||(w={}));const x=t=>t.split(" "),b=t=>x(t).includes(g.Right),E=t=>x(t).includes(g.Bottom),$=t=>x(t).includes(g.Full),v=t=>x(t).includes(g.Enclose),A=t=>t.includes(g.Curly)&&t.includes(g.Full);function S(t,e,o,n){if("a"===o&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===o?n:"a"===o?n.call(t):n?n.value:e.get(t)}function C(t,e,o,n,i){if("m"===n)throw new TypeError("Private method is not writable");if("a"===n&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===n?i.call(t,o):i?i.value=o:e.set(t,o),o}const O=()=>"_"+Math.random().toString(36).substring(2,11),B=t=>t.top,R=t=>t.left+t.width,P=t=>t.top+t.height,T=t=>t.left,L=t=>t.left+t.width/2,_=t=>t.top+t.height/2,k={center:t=>({x:L(t),y:_(t)}),top:t=>({x:L(t),y:B(t)}),right:t=>({x:R(t),y:_(t)}),bottom:t=>({x:L(t),y:P(t)}),left:t=>({x:T(t),y:_(t)}),"right-top":t=>({x:R(t),y:B(t)}),"right-bottom":t=>({x:R(t),y:P(t)}),"left-top":t=>({x:T(t),y:B(t)}),"left-bottom":t=>({x:T(t),y:P(t)}),"top-left":t=>({x:T(t),y:B(t)}),"top-right":t=>({x:R(t),y:B(t)}),"bottom-left":t=>({x:T(t),y:P(t)}),"bottom-right":t=>({x:R(t),y:P(t)}),"top-center":t=>({x:L(t),y:B(t)}),"right-center":t=>({x:R(t),y:_(t)}),"bottom-center":t=>({x:L(t),y:P(t)}),"left-center":t=>({x:T(t),y:_(t)})},M=async(t,e="center")=>{if(!e)throw new Error("No position given");if("string"!=typeof e)throw new 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 new Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await s();const n=t.getBoundingClientRect();return k[e](n)},j=async(t,e,o="center",n="center")=>{if(!t||!e)throw new Error("No element given");const{x:i,y:r}=await M(t,o),{x:s,y:a}=await M(e,n);return{x1:i,y1:r,x2:s,y2:a}},N=(t,e)=>{const{x1:o,x2:n,y1:i,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:p}=e;let c={x:o+(n-o)/2,y:i},l={x:o+(n-o)/2,y:r};return s&&(a?"west"===p?(c={x:o-32,y:i-8},l={x:n+32,y:r}):"south"===p?(c={x:o-8,y:i+32},l={x:n,y:r-32}):"east"===p?(c={x:o+32,y:i-8},l={x:n-32,y:r}):(c={x:o-8,y:i-32},l={x:n,y:r+32}):"west"===p?(c={x:o-32,y:i+8},l={x:n+32,y:r}):"south"===p?(c={x:o+8,y:i+32},l={x:n,y:r-32}):"east"===p?(c={x:o+32,y:i+8},l={x:n-32,y:r}):(c={x:o+8,y:i-32},l={x:n,y:r+32})),{firstPoint:{x:o,y:i},firstControl:c,lastPoint:{x:n,y:r},lastControl:l}},W=async(t,e,o)=>{const{pos1:n,pos2:i,firstSet:r=!1,direction:s}=o,{x1:a,y1:p,x2:c,y2:l}=await j(t,e,n,i);let h=0,d=0;"north"==s?d=8:"west"==s?h=8:"east"==s?h=-8:"south"==s&&(d=-8);const f=N({x1:a+0,x2:c+h,y1:p+0,y2:l+d},{direct:!0,firstSet:r,direction:s}),{firstPoint:u,firstControl:m,lastControl:g,lastPoint:w}=f;return`M ${u.x} ${u.y}C ${m.x} ${m.y}, ${g.x} ${g.y}, ${w.x} ${w.y}`},z=async({start:t,stop:e,crude:o=!1})=>{const{x1:n,y1:i,x2:r,y2:s}=await j(t,e),a=((t,e,o,n,i=!0)=>{if(!(t&&e&&o&&n))throw new SyntaxError("Missing input for `angle`");if("number"!=typeof t||"number"!=typeof e||"number"!=typeof o||"number"!=typeof n)throw new TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof o} ${typeof n}`);const r=n-e,s=o-t;let a=Math.atan2(r,s);return a*=180/Math.PI,i&&a<0&&(a=360+a),a})(n,i,r,s);return o?(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"})(a):(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"})(a)};var I,q,H,V,F,D,G,X,Y;class J{constructor(t,e){I.add(this),q.set(this,void 0),H.set(this,void 0),S(this,I,"m",V).call(this,t,e)}connect(){this.draw(S(this,H,"f"))}async draw(t){if(!t)throw new Error("No path given to draw!");const e=`ph_draw_path-path-${O()}`,o=t.cloneNode(!1);if(o.setAttribute("id",e),o.setAttribute("data-start-el",this.startElement.getAttribute("id")||"no-id-found"),o.classList.remove("original"),o.classList.add("speccer"),!t.parentNode)throw new Error("No parentNode found for path");this.line=t.parentNode.insertBefore(o,t.nextSibling);const n=await z({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:i,pos2:r}=(t=>{let e,o;switch(t){case"east":e="right",o="left";break;case"south":e="bottom",o="top";break;case"west":e="left",o="right";break;default:e="top",o="bottom"}return{pos1:e,pos2:o}})(n),s=await(async(t,e,o)=>{const{pos1:n,pos2:i}=o,{x1:r,y1:s,x2:a,y2:p}=await j(t,e,n,i),c=N({x1:r,x2:a,y1:s,y2:p},{direction:""}),{firstPoint:l,firstControl:h,lastControl:d,lastPoint:f}=c;return`M ${l.x} ${l.y}C ${h.x} ${h.y}, ${d.x} ${d.y}, ${f.x} ${f.y}`})(this.startElement,this.stopElement,{pos1:i,pos2:r});this.line.setAttribute("data-direction",n),this.line.setAttribute("data-pos1",i),this.line.setAttribute("data-pos2",r),this.line.setAttribute("d",s)}}q=new WeakMap,H=new WeakMap,I=new WeakSet,V=function(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,C(this,q,document.getElementById("ph-speccer-svg"),"f"),C(this,H,document.getElementById("ph-speccer-path"),"f"),!S(this,H,"f")||!S(this,q,"f"))throw new Error("Missing required SVG element to draw lines. Please see the documentation");this.connect()},window.DrawSVGLine=J;class K{constructor(t,e){F.add(this),D.set(this,void 0),G.set(this,void 0),S(this,F,"m",X).call(this,t,e)}connect(){this.draw(S(this,G,"f"))}async draw(t){if(!t)throw new Error("No path given to draw!");const e=S(this,F,"m",Y).call(this,t),o=S(this,F,"m",Y).call(this,t);if(!t.parentNode)throw new Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(o,t.nextSibling);const n=await z({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:i,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,o,n,i;switch(t){case"east":e="right-top",o="left-center",n="right-bottom",i="left-center";break;case"south":e="bottom-left",o="top-center",n="bottom-right",i="top-center";break;case"west":e="left-top",o="right-center",n="left-bottom",i="right-center";break;default:e="top-left",o="bottom-center",n="top-right",i="bottom-center"}return{path1pos1:e,path1pos2:o,path2pos1:n,path2pos2:i}})(n),p=await W(this.startElement,this.stopElement,{pos1:i,pos2:r,firstSet:!0,direction:n}),c=await W(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:n});this.firstPathElement.setAttribute("data-direction",n),this.firstPathElement.setAttribute("data-pos1",i),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",p),this.secondPathElement.setAttribute("data-direction",n),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",c)}}D=new WeakMap,G=new WeakMap,F=new WeakSet,X=function(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,C(this,D,document.getElementById("ph-speccer-svg"),"f"),C(this,G,document.getElementById("ph-speccer-path"),"f"),!S(this,G,"f")||!S(this,D,"f"))throw new Error("Missing required SVG element to draw lines. Please see the documentation");this.connect()},Y=function(t){if(!t)throw new Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${O()}`,o=t.cloneNode(!1);return o.setAttribute("data-start-el",this.startElement.getAttribute("id")||"no-id-found"),o.setAttribute("id",e),o.classList.remove("original"),o.classList.add("speccer"),o},window.DrawSVGCurlyBracket=K;const Q=async(t,e,o,n)=>{const{isCurly:s=!1}=n||{},a=r(o),p=i(getComputedStyle(o).getPropertyValue("--ph-speccer-measure-size"))||8;const c=await d(o,e);if(v(t)){const{left:t,top:e,height:o,width:n}=c.absolute();return{left:`${t}px`,top:`${e}px`,height:`${o}px`,width:`${n}px`}}if(x(t).includes(g.Left)){if($(t)&&!s){const{left:t,top:e,height:o}=c.fromLeft({sourceWidth:p});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}{const{left:t,top:e}=c.fromLeft({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if(b(t)){if($(t)&&!s){const{left:t,top:e,height:o}=c.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}{const{left:t,top:e}=c.fromRight({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if(E(t)){if($(t)&&!s){const{left:t,top:e,width:o}=c.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}{const{left:t,top:e}=c.fromBottom({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if($(t)&&!s){const{left:t,top:e,width:o}=c.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}{const{left:t,top:e}=c.fromTop({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}},U=(t="",n,i="span")=>{const r=document.createElement(i),s=document.createTextNode(t),a={};null!==n&&""!==n&&(a[n]=!0),!$(n)&&!v(n)||$(n)&&A(n)?r.appendChild(s):($(n)||v(n))&&r.setAttribute("data-dissection-counter",t);const p=o("ph speccer dissection",a);return e(r,p),r},Z=t=>{if(!t)return;const e=t.querySelectorAll("[data-anatomy]");if(e){let t=0;e.forEach((async(e,o)=>{if(!e)return Promise.resolve();const i=e.getAttribute("data-anatomy")||"";if(!i||""===i||-1===i.indexOf(g.Outline))return;let r=n[o];r||(r=`${n[t]}${n[t].toLowerCase()}`,t++);const s=U(r,i);document.body.appendChild(s);const p=await Q(i,e,s,{isCurly:A(i)});var c;await a(s,p),(c=i).includes(g.SVG)||c.includes(g.Curly)||c.includes(g.Full)||c.includes(g.Enclose)?new J(e,s):A(i)&&new K(e,s)}))}};const tt=(t="",o="",n="span")=>{const i=document.createElement(n);return i.setAttribute("title",t+"px"),i.setAttribute("data-measure",parseInt(t+"",10)+"px"),e(i,`ph speccer measure ${o}`),i},et=async t=>{if(!t)return;const e=t.getAttribute("data-speccer-measure");if(""===e||!e)return;const o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;await s();const n=t.getBoundingClientRect();if(x(e).includes(w.Width))if(E(e)){const o=tt(n.width,e);document.body.appendChild(o);const i=await d(o,t),{left:r,top:s,width:p}=i.fromBottom({center:!1});await a(o,{left:`${r}px`,top:`${s}px`,width:`${p}px`})}else{const o=tt(n.width,e);document.body.appendChild(o);const i=await d(o,t),{left:r,top:s,width:p}=i.fromTop({center:!1,modifier:-8});await a(o,{left:`${r}px`,top:`${s}px`,width:`${p}px`})}else if((t=>x(t).includes(w.Height))(e))if(b(e)){const o=tt(n.height,e);document.body.appendChild(o);const i=await d(o,t),{left:r,top:s,height:p}=i.fromRight({center:!1});await a(o,{left:`${r}px`,top:`${s}px`,height:`${p}px`})}else{const o=tt(n.height,e);document.body.appendChild(o);const i=await d(o,t),{left:r,top:s,height:p}=i.fromLeft({center:!1,modifier:-8});await a(o,{left:`${r}px`,top:`${s}px`,height:`${p}px`})}};const ot=(t="span")=>{const n=document.createElement(t),i=o("ph speccer mark");return e(n,i),n};const nt=(t,e=3)=>parseFloat(t+"").toFixed(e),it=(t,n)=>{const i=document.createElement("div"),r={};null!==n&&""!==n&&(r[n]=!0);const s=o("ph speccer typography",r);return i.innerHTML=t,e(i,s),i};const rt=t=>{const e=()=>((t,e,o=!1)=>{let n;return function(i,...r){const s=o&&!n;n&&clearTimeout(n),n=setTimeout((function(){n=null,o||t.apply(i,r)}),e),s&&t.apply(i,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},st=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},at=()=>{const t=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(u(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)").forEach((e=>{t.observe(e)}));const e=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(et(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-speccer-measure]").forEach((t=>{e.observe(t)}));const o=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(Z(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-anatomy-section]").forEach((t=>{o.observe(t)}))},pt=t=>{window.speccer=t},ct=t=>{const e=document.currentScript;if(e){const o=e.getAttribute("src");!o||-1===o.indexOf("speccer.js")&&-1===o.indexOf("JaXpOK.js")||(e.hasAttribute("data-manual")?pt(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?st(t):e.hasAttribute("data-lazy")?at():st(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||rt(t))}};const lt=y,ht=Object.freeze({__proto__:null,create:U,element:Z}),dt=Object.freeze({__proto__:null,element:et}),ft=Object.freeze({__proto__:null,create:ot,element:async t=>{if(!t)return Promise.resolve();const e=ot();document.body.appendChild(e);const o=await d(e,t),{left:n,top:i,height:r,width:s}=o.absolute(),p={left:`${n}px`,top:`${i}px`,height:`${r}px`,width:`${s}px`};await a(e,p)}}),ut=Object.freeze({__proto__:null,create:it,element:async t=>{if(!t)return;const e=t.getAttribute("data-speccer-typography"),o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;t.classList.add("is-specced");const n=await(async t=>{const e=(t=>{const{lineHeight:e,letterSpacing:o,fontFamily:n,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:o,fontFamily:n,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await p(t)),o="normal"!==e.lineHeight?parseInt(e.lineHeight,10)/16+"rem":"normal";return`\nfont-styles: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${e.fontFamily};</li> <li><span class="property">font-size:</span> ${e.fontSize} / ${parseInt(e.fontSize,10)/16}rem;</li> <li><span class="property">font-weight:</span> ${e.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${e.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${e.lineHeight} / ${o};</li> <li><span class="property">letter-spacing:</span> ${e.letterSpacing};</li> <li><span class="property">font-style:</span> ${e.fontStyle};</li></ul>}`})(t),i=it(n,e);document.body.appendChild(i);const s=await(async(t,e,o)=>{const n=e.getBoundingClientRect(),i=r(o),s=o.getBoundingClientRect(),a=await h(e),p=a.left-s.width-i+"px",d=nt(l(a.top,s,n))+"px",f=a.left+n.width+i+"px",u=nt(l(a.top,s,n))+"px",g=nt(c(a.left,s,n))+"px",w=a.top-s.height-i+"px",y=nt(c(a.left,s,n))+"px",x=a.top+n.height+i+"px";let b={left:p,top:d};return t&&-1!==t.indexOf(m.Right)?b={left:f,top:u}:t&&-1!==t.indexOf(m.Top)?b={left:g,top:w}:t&&-1!==t.indexOf(m.Bottom)&&(b={left:y,top:x}),b})(e,t,i);a(i,s)}}),mt=Object.freeze({__proto__:null,dom:st,lazy:at,manual:pt,activate:ct}),gt=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".speccer");const t=document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"),e=document.querySelectorAll("[data-speccer-measure]"),o=document.querySelectorAll("[data-speccer-typography]"),n=document.querySelectorAll("[data-anatomy-section]");document.querySelectorAll("[data-speccer-mark]").forEach(ft.element),t.forEach(lt.element),e.forEach(dt.element),o.forEach(ut.element),n.forEach(ht.element)};ct(gt),t.default=gt,t.dissect=ht,t.mark=ft,t.measure=dt,t.modes=mt,t.spacing=lt,t.typography=ut,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
1
|
+
!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,e,o="noop")=>{t&&(!e||e&&0===e.length||e.trim().split(" ").filter((t=>t!==o)).forEach((e=>t.classList.add(e))))},o=(t,e)=>t?e||"string"==typeof t?`${t} ${e?Object.keys(e).filter((t=>e[t])).join(" "):""}`.trim():`${Object.keys(t).filter((e=>t[e])).join(" ")}`.trim():"",i=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],n=t=>parseInt(t,10),r=t=>n(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,s=()=>new Promise(requestAnimationFrame),a=async(t,e)=>{!t||!e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e||Array.isArray(e)&&0===e.length||0===Object.keys(e).length&&e.constructor===Object||(await s(),Array.isArray(e)?e.forEach((e=>t.style[e.key]=e.value)):Object.keys(e).forEach((o=>t.style[o]=e[o])))},p=async t=>(await s(),getComputedStyle(t,null)),l=(t,e,o)=>t-e.width/2+o.width/2,c=(t,e,o)=>t-e.height/2+o.height/2,h=async t=>{await s();const e=t.getBoundingClientRect(),o=e.top+window.scrollY,i=e.left+window.scrollX;return{height:e.height,width:e.width,top:o,left:i}},d=async(t,e)=>{await s();const o=t.getBoundingClientRect(),i=await h(e),n=await(async(t,e)=>{await s();const o=t.getBoundingClientRect(),i=e.getBoundingClientRect(),n=i.top+window.scrollY,r=i.left+window.scrollX;return{height:i.height,width:i.width,top:c(n,o,i),left:l(r,o,i)}})(t,e),r=i.height,a=i.width,p=o.height,d=o.width;return{absolute:()=>({top:i.top,left:i.left,height:r,width:a}),toTop:({center:t=!1,sourceHeight:e=p,modifier:o=0}={})=>({top:i.top+e+o,left:t?n.left:i.left,height:r,width:a}),fromTop:({center:t=!1,sourceHeight:e=p,modifier:o=0}={})=>({top:i.top-e-o,left:t?n.left:i.left,height:r,width:a}),toBottom:({center:t=!1,sourceHeight:e=p,targetHeight:o=r,modifier:s=0}={})=>({top:i.top+o-(e+s),left:t?n.left:i.left,height:r,width:a}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:o=0}={})=>({top:i.top+e+o,left:t?n.left:i.left,height:r,width:a}),toLeft:({center:t=!1,sourceWidth:e=d,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left+e+o,height:r,width:a}),fromLeft:({center:t=!1,sourceWidth:e=d,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left-e-o,height:r,width:a}),toRight:({center:t=!1,sourceWidth:e=d,targetWidth:o=a,modifier:s=0}={})=>({top:t?n.top:i.top,left:i.left+o-(e+s),height:r,width:a}),fromRight:({center:t=!1,targetWidth:e=a,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left+e+o,height:r,width:a})}},f=(t="",o="span")=>{const i=document.createElement(o),n=document.createTextNode(t+"");return i.appendChild(n),i.setAttribute("title",t+"px"),e(i,"ph speccer spacing"),i},u=async t=>{if(!t)return;const o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;const i=(t=>{const{marginTop:e,marginBottom:o,marginLeft:i,marginRight:n,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}=t;return{marginTop:e,marginBottom:o,marginLeft:i,marginRight:n,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}})(o),r=Object.keys(i).filter((t=>"0px"!==i[t]));0!==r.length&&r.forEach((async o=>{const r=n(i[o]),p=f(r),l=(t=>-1!==t.indexOf("Top")?t.replace("Top"," top"):-1!==t.indexOf("Right")?t.replace("Right"," right"):-1!==t.indexOf("Bottom")?t.replace("Bottom"," bottom"):-1!==t.indexOf("Left")?t.replace("Left"," left"):"")(o);e(p,l),document.body.appendChild(p),t.classList.add("is-specced"),await(async(t,e,o,i)=>{await s();const n=i.getBoundingClientRect(),r=await h(i);"marginTop"===t&&a(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top-e+"px"}),"marginRight"===t&&a(o,{height:n.height+"px",width:`${e}px`,left:r.left+parseInt(n.width+"",10)+"px",top:r.top+"px"}),"marginBottom"===t&&a(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+parseInt(n.height+"",10)+"px"}),"marginLeft"===t&&a(o,{height:n.height+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}),"paddingTop"===t&&a(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+"px"}),"paddingBottom"===t&&a(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+(parseInt(n.height+"",10)-e)+"px"}),"paddingRight"===t&&a(o,{height:n.height+"px",width:`${e}px`,left:r.left+(parseInt(n.width+"",10)-e)+"px",top:r.top+"px"}),"paddingLeft"===t&&a(o,{height:n.height+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"})})(o,r,p,t)}))};var m,g,w;!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(m||(m={})),function(t){t.Outline="outline",t.Enclose="enclose",t.Full="full",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(g||(g={})),function(t){t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(w||(w={}));const y=t=>t.split(" "),x=t=>y(t).includes(g.Right),b=t=>y(t).includes(g.Bottom),E=t=>y(t).includes(g.Full),$=t=>y(t).includes(g.Enclose),v=t=>t.includes(g.Curly)&&t.includes(g.Full),A=()=>"_"+Math.random().toString(36).substring(2,11),P=t=>t.top,S=t=>t.left+t.width,C=t=>t.top+t.height,B=t=>t.left+t.width/2,R=t=>t.top+t.height/2,L={center:t=>({x:B(t),y:R(t)}),top:t=>({x:B(t),y:P(t)}),right:t=>({x:S(t),y:R(t)}),bottom:t=>({x:B(t),y:C(t)})},O=async(t,e="center")=>{if(!e)throw new Error("No position given");if("string"!=typeof e)throw new 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 new Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await s();const i=t.getBoundingClientRect();return L[e](i)},T=async(t,e,o="center",i="center")=>{if(!t||!e)throw new Error("No element given");const{x:n,y:r}=await O(t,o),{x:s,y:a}=await O(e,i);return{x1:n,y1:r,x2:s,y2:a}},N=(t,e)=>{const{x1:o,x2:i,y1:n,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:p}=e;let l={x:o+(i-o)/2,y:n},c={x:o+(i-o)/2,y:r};return s&&(a?"west"===p?(l={x:o-32,y:n-8},c={x:i+32,y:r}):"south"===p?(l={x:o-8,y:n+32},c={x:i,y:r-32}):"east"===p?(l={x:o+32,y:n-8},c={x:i-32,y:r}):(l={x:o-8,y:n-32},c={x:i,y:r+32}):"west"===p?(l={x:o-32,y:n+8},c={x:i+32,y:r}):"south"===p?(l={x:o+8,y:n+32},c={x:i,y:r-32}):"east"===p?(l={x:o+32,y:n+8},c={x:i-32,y:r}):(l={x:o+8,y:n-32},c={x:i,y:r+32})),{firstPoint:{x:o,y:n},firstControl:l,lastPoint:{x:i,y:r},lastControl:c}},M=async(t,e,o)=>{const{pos1:i,pos2:n,firstSet:r=!1,direction:s}=o,{x1:a,y1:p,x2:l,y2:c}=await T(t,e,i,n);let h=0,d=0;"north"==s?d=8:"west"==s?h=8:"east"==s?h=-8:"south"==s&&(d=-8);const f=N({x1:a+0,x2:l+h,y1:p+0,y2:c+d},{direct:!0,firstSet:r,direction:s}),{firstPoint:u,firstControl:m,lastControl:g,lastPoint:w}=f;return`M ${u.x} ${u.y}C ${m.x} ${m.y}, ${g.x} ${g.y}, ${w.x} ${w.y}`},I=async({start:t,stop:e,crude:o=!1})=>{const{x1:i,y1:n,x2:r,y2:s}=await T(t,e),a=((t,e,o,i,n=!0)=>{if(!(t&&e&&o&&i))throw new SyntaxError("Missing input for `angle`");if("number"!=typeof t||"number"!=typeof e||"number"!=typeof o||"number"!=typeof i)throw new TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof o} ${typeof i}`);const r=i-e,s=o-t;let a=Math.atan2(r,s);return a*=180/Math.PI,n&&a<0&&(a=360+a),a})(i,n,r,s);return o?(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"})(a):(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"})(a)};class k{#t;#e;startElement;stopElement;line;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");this.connect()}connect(){this.draw(this.#e)}async draw(t){if(!t)throw new Error("No path given to draw!");const e=`ph_draw_path-path-${A()}`,o=t.cloneNode(!1);if(o.setAttribute("id",e),o.setAttribute("data-start-el",this.startElement.getAttribute("id")||"no-id-found"),o.classList.remove("original"),o.classList.add("speccer"),!t.parentNode)throw new Error("No parentNode found for path");this.line=t.parentNode.insertBefore(o,t.nextSibling);const i=await I({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:n,pos2:r}=(t=>{let e,o;switch(t){case"east":e="right",o="left";break;case"south":e="bottom",o="top";break;case"west":e="left",o="right";break;default:e="top",o="bottom"}return{pos1:e,pos2:o}})(i),s=await(async(t,e,o)=>{const{pos1:i,pos2:n}=o,{x1:r,y1:s,x2:a,y2:p}=await T(t,e,i,n),l=N({x1:r,x2:a,y1:s,y2:p},{direction:""}),{firstPoint:c,firstControl:h,lastControl:d,lastPoint:f}=l;return`M ${c.x} ${c.y}C ${h.x} ${h.y}, ${d.x} ${d.y}, ${f.x} ${f.y}`})(this.startElement,this.stopElement,{pos1:n,pos2:r});this.line.setAttribute("data-direction",i),this.line.setAttribute("data-pos1",n),this.line.setAttribute("data-pos2",r),this.line.setAttribute("d",s)}}window.DrawSVGLine=k;class q{#t;#e;startElement;stopElement;firstPathElement;secondPathElement;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");this.connect()}connect(){this.draw(this.#e)}#i(t){if(!t)throw new Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${A()}`,o=t.cloneNode(!1);return o.setAttribute("data-start-el",this.startElement.getAttribute("id")||"no-id-found"),o.setAttribute("id",e),o.classList.remove("original"),o.classList.add("speccer"),o}async draw(t){if(!t)throw new Error("No path given to draw!");const e=this.#i(t),o=this.#i(t);if(!t.parentNode)throw new Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(o,t.nextSibling);const i=await I({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:n,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,o,i,n;switch(t){case"east":e="right-top",o="left-center",i="right-bottom",n="left-center";break;case"south":e="bottom-left",o="top-center",i="bottom-right",n="top-center";break;case"west":e="left-top",o="right-center",i="left-bottom",n="right-center";break;default:e="top-left",o="bottom-center",i="top-right",n="bottom-center"}return{path1pos1:e,path1pos2:o,path2pos1:i,path2pos2:n}})(i),p=await M(this.startElement,this.stopElement,{pos1:n,pos2:r,firstSet:!0,direction:i}),l=await M(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:i});this.firstPathElement.setAttribute("data-direction",i),this.firstPathElement.setAttribute("data-pos1",n),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",p),this.secondPathElement.setAttribute("data-direction",i),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",l)}}window.DrawSVGCurlyBracket=q;const H=async(t,e,o,i)=>{const{isCurly:s=!1}=i||{},a=r(o),p=n(getComputedStyle(o).getPropertyValue("--ph-speccer-measure-size"))||8;const l=await d(o,e);if($(t)){const{left:t,top:e,height:o,width:i}=l.absolute();return{left:`${t}px`,top:`${e}px`,height:`${o}px`,width:`${i}px`}}if(y(t).includes(g.Left)){if(E(t)&&!s){const{left:t,top:e,height:o}=l.fromLeft({sourceWidth:p});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}{const{left:t,top:e}=l.fromLeft({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if(x(t)){if(E(t)&&!s){const{left:t,top:e,height:o}=l.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}{const{left:t,top:e}=l.fromRight({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if(b(t)){if(E(t)&&!s){const{left:t,top:e,width:o}=l.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}{const{left:t,top:e}=l.fromBottom({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}}if(E(t)&&!s){const{left:t,top:e,width:o}=l.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}{const{left:t,top:e}=l.fromTop({center:!0,modifier:s?a/1.5:a});return{left:`${t}px`,top:`${e}px`}}},j=(t="",i,n="span")=>{const r=document.createElement(n),s=document.createTextNode(t),a={};null!==i&&""!==i&&(a[i]=!0),!E(i)&&!$(i)||E(i)&&v(i)?r.appendChild(s):(E(i)||$(i))&&r.setAttribute("data-dissection-counter",t);const p=o("ph speccer dissection",a);return e(r,p),r},V=t=>{if(!t)return Promise.resolve();const e=t.querySelectorAll("[data-anatomy]");if(e){let t=0;e.forEach((async(e,o)=>{if(!e)return Promise.resolve();const n=e.getAttribute("data-anatomy")||"";if(!n||""===n||-1===n.indexOf(g.Outline))return Promise.resolve();let r=i[o];r||(r=`${i[t]}${i[t].toLowerCase()}`,t++);const s=j(r,n);document.body.appendChild(s);const p=await H(n,e,s,{isCurly:v(n)});var l;await a(s,p),(l=n).includes(g.SVG)||l.includes(g.Curly)||l.includes(g.Full)||l.includes(g.Enclose)?new k(e,s):v(n)&&new q(e,s)}))}return Promise.resolve()},W=(t="",o="",i="span")=>{const n=document.createElement(i);return n.setAttribute("title",t+"px"),n.setAttribute("data-measure",parseInt(t+"",10)+"px"),e(n,`ph speccer measure ${o}`),n},z=async t=>{if(!t)return;const e=t.getAttribute("data-speccer-measure");if(""===e||!e)return;const o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;await s();const i=t.getBoundingClientRect();if(y(e).includes(w.Width))if(b(e)){const o=W(i.width,e);document.body.appendChild(o);const n=await d(o,t),{left:r,top:s,width:p}=n.fromBottom({center:!1});await a(o,{left:`${r}px`,top:`${s}px`,width:`${p}px`})}else{const o=W(i.width,e);document.body.appendChild(o);const n=await d(o,t),{left:r,top:s,width:p}=n.fromTop({center:!1,modifier:-8});await a(o,{left:`${r}px`,top:`${s}px`,width:`${p}px`})}else if((t=>y(t).includes(w.Height))(e))if(x(e)){const o=W(i.height,e);document.body.appendChild(o);const n=await d(o,t),{left:r,top:s,height:p}=n.fromRight({center:!1});await a(o,{left:`${r}px`,top:`${s}px`,height:`${p}px`})}else{const o=W(i.height,e);document.body.appendChild(o);const n=await d(o,t),{left:r,top:s,height:p}=n.fromLeft({center:!1,modifier:-8});await a(o,{left:`${r}px`,top:`${s}px`,height:`${p}px`})}},F=(t="span")=>{const i=document.createElement(t),n=o("ph speccer mark");return e(i,n),i},D=async t=>{if(!t)return Promise.resolve();const e=F();document.body.appendChild(e);const o=await d(e,t),{left:i,top:n,height:r,width:s}=o.absolute(),p={left:`${i}px`,top:`${n}px`,height:`${r}px`,width:`${s}px`};await a(e,p)},G=(t,e=3)=>parseFloat(t+"").toFixed(e),_=(t,i)=>{const n=document.createElement("div"),r={};null!==i&&""!==i&&(r[i]=!0);const s=o("ph speccer typography",r);return n.innerHTML=t,e(n,s),n},X=async t=>{if(!t)return;const e=t.getAttribute("data-speccer-typography"),o=await p(t);if("none"===o.display||"0"===o.opacity||"hidden"===o.visibility)return;t.classList.add("is-specced");const i=await(async t=>{const e=(t=>{const{lineHeight:e,letterSpacing:o,fontFamily:i,fontSize:n,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:o,fontFamily:i,fontSize:n,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await p(t)),o="normal"!==e.lineHeight?parseInt(e.lineHeight,10)/16+"rem":"normal";return`\nfont-styles: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${e.fontFamily};</li> <li><span class="property">font-size:</span> ${e.fontSize} / ${parseInt(e.fontSize,10)/16}rem;</li> <li><span class="property">font-weight:</span> ${e.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${e.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${e.lineHeight} / ${o};</li> <li><span class="property">letter-spacing:</span> ${e.letterSpacing};</li> <li><span class="property">font-style:</span> ${e.fontStyle};</li></ul>}`})(t),n=_(i,e);document.body.appendChild(n);const s=await(async(t,e,o)=>{const i=e.getBoundingClientRect(),n=r(o),s=o.getBoundingClientRect(),a=await h(e),p=a.left-s.width-n+"px",d=G(c(a.top,s,i))+"px",f=a.left+i.width+n+"px",u=G(c(a.top,s,i))+"px",g=G(l(a.left,s,i))+"px",w=a.top-s.height-n+"px",y=G(l(a.left,s,i))+"px",x=a.top+i.height+n+"px";let b={left:p,top:d};return t&&-1!==t.indexOf(m.Right)?b={left:f,top:u}:t&&-1!==t.indexOf(m.Top)?b={left:g,top:w}:t&&-1!==t.indexOf(m.Bottom)&&(b={left:y,top:x}),b})(e,t,n);a(n,s)},Y=t=>{const e=()=>((t,e,o=!1)=>{let i;return function(n,...r){const s=o&&!i;i&&clearTimeout(i),i=setTimeout((function(){i=null,o||t.apply(n,r)}),e),s&&t.apply(n,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},J=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},K=()=>{const t=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(u(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)").forEach((e=>{t.observe(e)}));const e=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(z(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-speccer-measure]").forEach((t=>{e.observe(t)}));const o=new IntersectionObserver(((t,e)=>{t.forEach((t=>{t.intersectionRatio>0&&(V(t.target),e.unobserve(t.target))}))}));document.querySelectorAll("[data-anatomy-section]").forEach((t=>{o.observe(t)}))},Q=t=>{window.speccer=t},U=t=>{const e=document.currentScript;if(e){const o=e.getAttribute("src");!o||-1===o.indexOf("speccer.js")&&-1===o.indexOf("JaXpOK.js")||(e.hasAttribute("data-manual")?Q(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?J(t):e.hasAttribute("data-lazy")?K():J(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||Y(t))}},Z={create:f,element:u},tt={create:j,element:V},et={create:W,element:z},ot={create:F,element:D},it={create:_,element:X},nt={dom:J,lazy:K,manual:Q,activate:U},rt=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".speccer");const t=document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"),e=document.querySelectorAll("[data-speccer-measure]"),o=document.querySelectorAll("[data-speccer-typography]"),i=document.querySelectorAll("[data-anatomy-section]");document.querySelectorAll("[data-speccer-mark]").forEach(D),t.forEach(u),e.forEach(z),o.forEach(X),i.forEach(V)};U(rt),t.default=rt,t.dissect=tt,t.mark=ot,t.measure=et,t.modes=nt,t.spacing=Z,t.typography=it,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
2
2
|
//# sourceMappingURL=speccer.js.map
|
package/speccer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speccer.js","sources":["src/utils/node.ts","src/utils/classnames.ts","src/utils/constants.ts","src/utils/css.ts","src/utils/wait.ts","src/utils/styles.ts","src/utils/position.ts","src/features/spacing/index.ts","src/features/spacing/utils/position.ts","src/types/enums/area.ts","src/utils/area.ts","node_modules/tslib/tslib.es6.js","src/utils/id.ts","src/utils/coords.ts","src/utils/xy.ts","src/utils/intrinsic-coords.ts","src/utils/get-coords-pair-from-objects.ts","src/utils/bezier.ts","src/utils/direction-of-element.ts","src/utils/angle.ts","src/utils/cardinal.ts","src/utils/classes/DrawSVGLine.ts","src/utils/classes/DrawSVGCurlyBracket.ts","src/features/dissect/utils/styles.ts","src/features/dissect/index.ts","src/features/measure/index.ts","src/features/mark/index.ts","src/utils/number.ts","src/features/typography/index.ts","src/utils/debounce.ts","src/utils/resize.ts","src/config/browser.ts","src/main.ts","src/features/typography/utils/template.ts","src/features/typography/utils/position.ts"],"sourcesContent":["/**\n * Inserts an HTML element after another element in the DOM.\n *\n * @param {HTMLElement | null} el - The reference element after which the new element will be inserted.\n * @param {HTMLElement} newSibling - The new element to be inserted.\n * @returns {Element|null}\n *\n * @example\n * // Insert an element after another element\n * const referenceElement = document.getElementById('reference-element');\n * const newElement = document.createElement('div');\n * after(referenceElement, newElement);\n */\nexport const after = (\n el: HTMLElement | null,\n newSibling: HTMLElement\n): Element | null => el && el.insertAdjacentElement('afterend', newSibling);\n\n/**\n * Removes all elements matching a selector from the DOM.\n *\n * @param {string} selector - The CSS selector used to select elements for removal.\n * @param {Document} el - The document context (default is the global `document` object).\n * @returns {void}\n *\n * @example\n * // Remove all elements with a specific class from the document\n * removeAll('.my-class');\n */\nexport const removeAll = (selector: string, el: Document = document): void => {\n [].forEach.call(el.querySelectorAll(selector), function (e: HTMLElement) {\n e.remove();\n });\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { ClassNamesObjectMapInterface } from 'types/interfaces/classnames';\n\n/**\n * Add CSS classes to an HTML element.\n *\n * @param {HTMLElement} el - The HTML element to which classes should be added.\n * @param {string} cls - The CSS classes to add, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid adding.\n * @returns {void}\n * @example\n * // Add classes to an HTML element\n * const element = document.getElementById('example');\n * set(element, 'class1 class2');\n */\nexport const set = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.add(cl));\n};\n\n/**\n * Toggle CSS classes on an HTML element.\n *\n * @param {HTMLElement} el - The HTML element on which classes should be toggled.\n * @param {string} cls - The CSS classes to toggle, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid toggling.\n * @returns {void}\n * @example\n * // Toggle classes on an HTML element\n * const element = document.getElementById('example');\n * toggle(element, 'class1 class2');\n */\nexport const toggle = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.toggle(cl));\n};\n\n/**\n * Remove CSS classes from an HTML element.\n *\n * @param {HTMLElement} el - The HTML element from which classes should be removed.\n * @param {string} cls - The CSS classes to remove, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid removing.\n * @returns {void}\n * @example\n * // Remove classes from an HTML element\n * const element = document.getElementById('example');\n * remove(element, 'class1 class2');\n */\nexport const remove = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.remove(cl));\n};\n\n/**\n * Generate CSS classes from a string and an object.\n *\n * @param {string} cls - Additional CSS classes as a string.\n * @param {ClassNamesObjectMapInterface} cls_obj - A mapping of class names to boolean values.\n * @returns {string} - A space-separated string of CSS class names.\n * @example\n * // Generate CSS classes from a string and an object\n * const classNames = cx('class1', { class2: true, class3: false });\n * console.log(classNames); // Example output: 'class1 class2'\n */\nexport const cx = (\n cls: string,\n cls_obj?: ClassNamesObjectMapInterface\n): string => {\n if (!cls) return '';\n\n if (!cls_obj && typeof cls !== 'string') {\n return `${Object.keys(cls)\n .filter((classname) => cls[classname])\n .join(' ')}`.trim();\n }\n\n return `${cls} ${\n cls_obj\n ? Object.keys(cls_obj)\n .filter((classname) => cls_obj[classname])\n .join(' ')\n : ''\n }`.trim();\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Array of uppercase letters.\n *\n * @type {string[]}\n * @example\n * // Access the array of uppercase letters\n * const letters = SPECCER_LITERALS;\n * console.log(letters); // Example output: ['A', 'B', 'C', ...]\n */\nexport const SPECCER_LITERALS = [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'];\n\n/**\n * Array of HTML tags to avoid when processing.\n *\n * @type {string[]}\n * @example\n * // Access the array of tags to avoid\n * const tagsToAvoid = SPECCER_TAGS_TO_AVOID;\n * console.log(tagsToAvoid); // Example output: ['TR', 'TH', 'TD', ...]\n */\nexport const SPECCER_TAGS_TO_AVOID = [\n 'TR',\n 'TH',\n 'TD',\n 'TBODY',\n 'THEAD',\n 'TFOOT'\n];\n\n/**\n * Default value for pin space.\n *\n * @type {number}\n * @example\n * // Access the default pin space value\n * const defaultPinSpace = SPECCER_DEFAULT_PIN_SPACE;\n * console.log(defaultPinSpace); // Example output: 48\n */\nexport const SPECCER_DEFAULT_PIN_SPACE = 48;\n\n/**\n * Negative default value for pin space.\n *\n * @type {number}\n * @example\n * // Access the negative default pin space value\n * const negativeDefaultPinSpace = SPECCER_DEFAULT_PIN_SPACE_NEG;\n * console.log(negativeDefaultPinSpace); // Example output: -48\n */\nexport const SPECCER_DEFAULT_PIN_SPACE_NEG = SPECCER_DEFAULT_PIN_SPACE * -1;\n\n/**\n * Default value for measure size.\n *\n * @type {number}\n * @example\n * // Access the default measure size value\n * const defaultMeasureSize = SPECCER_DEFAULT_MEASURE_SIZE;\n * console.log(defaultMeasureSize); // Example output: 8\n */\nexport const SPECCER_DEFAULT_MEASURE_SIZE = 8;\n\n/**\n * Negative default value for measure size.\n *\n * @type {number}\n * @example\n * // Access the negative default measure size value\n * const negativeDefaultMeasureSize = SPECCER_DEFAULT_MEASURE_SIZE_NEG;\n * console.log(negativeDefaultMeasureSize); // Example output: -8\n */\nexport const SPECCER_DEFAULT_MEASURE_SIZE_NEG =\n SPECCER_DEFAULT_MEASURE_SIZE * -1;\n\n/**\n * Default line width value.\n *\n * @type {number}\n * @example\n * // Access the default line width value\n * const defaultLineWidth = SPECCER_DEFAULT_LINE_WIDTH;\n * console.log(defaultLineWidth); // Example output: 1\n */\nexport const SPECCER_DEFAULT_LINE_WIDTH = 1;\n","/* eslint no-console:0 */\n'use strict';\nimport {\n SPECCER_DEFAULT_PIN_SPACE,\n SPECCER_DEFAULT_MEASURE_SIZE,\n SPECCER_DEFAULT_LINE_WIDTH\n} from './constants';\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\n\n/**\n * Parses a string value into an integer.\n *\n * @param {string} value - The string value to parse.\n * @returns {number} - The parsed integer value.\n *\n * @example\n * // Parse a string value into an integer\n * const intValue = getNumberValue(\"42\");\n * console.log(intValue); // Example output: 42\n */\nexport const getNumberValue = (value: string): number => parseInt(value, 10);\n\n/**\n * Normalizes a string or number value to ensure it's a valid number.\n * If the value is within the range [0, 1] or [-1, 0), it's normalized to 0.\n *\n * @param {string | number} value - The value to normalize.\n * @returns {number} - The normalized number value.\n *\n * @example\n * // Normalize a value to ensure it's a valid number\n * const normalizedValue = normalizeNumberValue(\"0.5\");\n * console.log(normalizedValue); // Example output: 0.5\n */\nexport const normalizeNumberValue = (value: string | number): number => {\n const _value = parseFloat(value + '');\n\n return (_value >= 0 && _value < 1) || (_value <= 0 && _value > -1)\n ? 0\n : _value;\n};\n\n/**\n * Converts a CSS property name with \"Top\", \"Right\", \"Bottom\", or \"Left\" into a class name.\n *\n * @param {string} property - The CSS property name.\n * @returns {string} - The corresponding class name.\n *\n * @example\n * // Convert a CSS property name to a class name\n * const className = getClassNameFromCSSProperty(\"marginTop\");\n * console.log(className); // Example output: \"margin top\"\n */\nexport const getClassNameFromCSSProperty = (property: string): string => {\n if (property.indexOf('Top') !== -1) {\n return property.replace('Top', ' top');\n } else if (property.indexOf('Right') !== -1) {\n return property.replace('Right', ' right');\n } else if (property.indexOf('Bottom') !== -1) {\n return property.replace('Bottom', ' bottom');\n } else if (property.indexOf('Left') !== -1) {\n return property.replace('Left', ' left');\n }\n\n return '';\n};\n\n/**\n * Extracts spacing-related CSS properties from a style object.\n *\n * @param {SpacingCSSPropertiesType} style - The style object.\n * @returns {SpacingCSSPropertiesType} - The extracted spacing-related properties.\n *\n * @example\n * // Extract spacing-related properties from a style object\n * const spacing = getSpacing({\n * marginTop: \"10px\",\n * marginLeft: \"20px\",\n * });\n * console.log(spacing); // Example output: { marginTop: \"10px\", marginLeft: \"20px\" }\n */\nexport const getSpacing = (\n style: SpacingCSSPropertiesType\n): SpacingCSSPropertiesType => {\n const {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n } = style;\n\n return {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n };\n};\n\n/**\n * Extracts typography-related CSS properties from a style object.\n *\n * @param {TypographyCSSPropertiesType} style - The style object.\n * @returns {TypographyCSSPropertiesType} - The extracted typography-related properties.\n *\n * @example\n * // Extract typography-related properties from a style object\n * const typography = getTypography({\n * fontSize: \"16px\",\n * fontWeight: \"bold\",\n * });\n * console.log(typography); // Example output: { fontSize: \"16px\", fontWeight: \"bold\" }\n */\nexport const getTypography = (\n style: TypographyCSSPropertiesType\n): TypographyCSSPropertiesType => {\n const {\n lineHeight,\n letterSpacing,\n fontFamily,\n fontSize,\n fontStyle,\n fontVariationSettings,\n fontWeight\n } = style;\n\n return {\n lineHeight,\n letterSpacing,\n fontFamily,\n fontSize,\n fontStyle,\n fontVariationSettings,\n fontWeight\n };\n};\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-pin-space\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * // Get the value of a custom CSS property from an element\n * const value = pinSpace(document.body);\n * console.log(value); // Example output: 10\n */\nexport const pinSpace = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-pin-space')\n ) || SPECCER_DEFAULT_PIN_SPACE;\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-measure-size\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * // Get the value of a custom CSS property from an element\n * const value = measureSize(document.body);\n * console.log(value); // Example output: 20\n */\nexport const measureSize = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-measure-size')\n ) || SPECCER_DEFAULT_MEASURE_SIZE;\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-line-width\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * // Get the value of a custom CSS property from an element\n * const value = lineWidth(document.body);\n * console.log(value); // Example output: 1.5\n */\nexport const lineWidth = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-line-width')\n ) || SPECCER_DEFAULT_LINE_WIDTH;\n","/**\n * Waits for the specified amount of time in milliseconds.\n *\n * @param {number} ms - The number of milliseconds to wait.\n * @returns {Promise<void>} - A Promise that resolves after the specified time.\n *\n * @example\n * // Wait for 1 second (1000 milliseconds)\n * await waitFor(1000);\n */\nexport const waitFor = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Waits for the next animation frame using requestAnimationFrame.\n *\n * @returns {Promise<number>} - A Promise that resolves with the timestamp of the next animation frame.\n *\n * @example\n * // Wait for the next animation frame and get the rect\n * await waitForFrame();\n * const rect = el.getBoundingClientRect();\n * // Wait for the next animation frame and get the timestamp\n * const timestamp = await waitForFrame();\n */\nexport const waitForFrame = (): Promise<number> =>\n new Promise(requestAnimationFrame);\n","/* eslint no-console:0 */\n'use strict';\nimport { waitForFrame } from './wait';\n\n/**\n * Adds CSS styles to an HTMLElement.\n *\n * @param {HTMLElement} el - The HTMLElement to apply styles to.\n * @param {object | Array<{ key: string; value: string }>} styles - An object or an array of objects containing CSS styles to apply.\n * @returns {Promise<void>} - A Promise that resolves after styles are applied.\n *\n * @example\n * // Apply styles as an object\n * const element = document.getElementById('my-element');\n * await add(element, { color: 'red', fontSize: '16px' });\n *\n * // Apply styles as an array of objects\n * const styles = [\n * { key: 'color', value: 'blue' },\n * { key: 'backgroundColor', value: 'yellow' }\n * ];\n * await add(element, styles);\n */\nexport const add = async (\n el: HTMLElement,\n styles: object | Array<{ key: string; value: string }>\n): Promise<void> => {\n if (\n !el ||\n !styles ||\n typeof styles === 'string' ||\n typeof styles === 'number' ||\n typeof styles === 'boolean' ||\n (Array.isArray(styles) && styles.length === 0) ||\n (Object.keys(styles).length === 0 && styles.constructor === Object)\n ) {\n return;\n }\n\n await waitForFrame();\n\n if (Array.isArray(styles)) {\n styles.forEach(\n (style: { key: string; value: string }) =>\n (el.style[style.key] = style.value)\n );\n } else {\n Object.keys(styles).forEach((key) => (el.style[key] = styles[key]));\n }\n};\n\n/**\n * Gets the computed CSS styles of an HTMLElement.\n *\n * @param {HTMLElement} el - The HTMLElement to get computed styles from.\n * @returns {Promise<CSSStyleDeclaration>} - A Promise that resolves with the computed CSS styles.\n *\n * @example\n * // Get computed styles of an element\n * const element = document.getElementById('my-element');\n * const computedStyles = await get(element);\n * console.log(computedStyles.color); // Logs the color property value\n */\nexport const get = async (el: HTMLElement): Promise<CSSStyleDeclaration> => {\n await waitForFrame();\n\n return getComputedStyle(el, null);\n};\n","import { waitForFrame } from './wait';\n\nimport { PositionPropertiesType, PositionInputType } from '../types/position';\nimport { GetRecPropertiesInterface } from 'types/interfaces/position';\n\n/**\n * Calculates the horizontal center of two elements.\n *\n * @param {number} modifier - A modifier value.\n * @param {DOMRect} startRect - The starting element's rectangle.\n * @param {DOMRect} targetRect - The target element's rectangle.\n * @returns {number} - The horizontal center position.\n *\n * @example\n * // Calculate the horizontal center of two elements\n * const center = get_horizontal_center_of_els(0, startRect, targetRect);\n */\nexport const get_horizontal_center_of_els = (\n modifier: number,\n startRect: DOMRect,\n targetRect: DOMRect\n): number => modifier - startRect.width / 2 + targetRect.width / 2;\n\n/**\n * Calculates the vertical center of two elements.\n *\n * @param {number} modifier - A modifier value.\n * @param {DOMRect} startRect - The starting element's rectangle.\n * @param {DOMRect} targetRect - The target element's rectangle.\n * @returns {number} - The vertical center position.\n *\n * @example\n * // Calculate the vertical center of two elements\n * const center = get_vertical_center_of_els(0, startRect, targetRect);\n */\nexport const get_vertical_center_of_els = (\n modifier: number,\n startRect: DOMRect,\n targetRect: DOMRect\n): number => modifier - startRect.height / 2 + targetRect.height / 2;\n\n/**\n * Gets the offset properties of an HTML element.\n *\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<PositionPropertiesType>} - A promise that resolves to the offset properties.\n *\n * @example\n * // Get the offset properties of an element\n * const offsetProps = await offset(targetElement);\n */\nexport const offset = async (\n targetEl: HTMLElement\n): Promise<PositionPropertiesType> => {\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.pageYOffset;\n const _el_offset_left = _target_rect.left + window.pageXOffset;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: _el_offset_top,\n left: _el_offset_left\n };\n};\n\n/**\n * Gets the offset properties of an HTML element with its center aligned to another element.\n *\n * @param {HTMLElement} sourceEl - The source HTML element.\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<PositionPropertiesType>} - A promise that resolves to the offset properties.\n *\n * @example\n * // Get the offset properties of an element with its center aligned to another element\n * const offsetProps = await offsetWithCenter(sourceElement, targetElement);\n */\nexport const offsetWithCenter = async (\n sourceEl: HTMLElement,\n targetEl: HTMLElement\n): Promise<PositionPropertiesType> => {\n await waitForFrame();\n\n const _source_rect = sourceEl.getBoundingClientRect();\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.pageYOffset;\n const _el_offset_left = _target_rect.left + window.pageXOffset;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: get_vertical_center_of_els(_el_offset_top, _source_rect, _target_rect),\n left: get_horizontal_center_of_els(\n _el_offset_left,\n _source_rect,\n _target_rect\n )\n };\n};\n\n/**\n * Gets various positioning properties between two HTML elements.\n *\n * @param {HTMLElement} sourceEl - The source HTML element.\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<GetRecPropertiesInterface>} - A promise that resolves to an object with positioning functions.\n *\n * @example\n * // Get positioning properties between two elements\n * const recProps = await getRec(sourceElement, targetElement);\n *\n * // Get the absolute position properties\n * const absoluteProps = recProps.absolute();\n *\n * // Get the position properties with the source element above the target element\n * const aboveProps = recProps.toTop();\n */\nexport const getRec = async (\n sourceEl: HTMLElement,\n targetEl: HTMLElement\n): Promise<GetRecPropertiesInterface> => {\n await waitForFrame();\n\n const _source_rect = sourceEl.getBoundingClientRect();\n const _target_offset = await offset(targetEl);\n const _target_offset_center = await offsetWithCenter(sourceEl, targetEl);\n const _target_height = _target_offset.height;\n const _target_width = _target_offset.width;\n const _source_height = _source_rect.height;\n const _source_width = _source_rect.width;\n\n return {\n absolute: (): PositionPropertiesType => {\n return {\n top: _target_offset.top,\n left: _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n toTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + sourceHeight + modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n fromTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top - sourceHeight - modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n toBottom: ({\n center = false,\n sourceHeight = _source_height,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + targetHeight - (sourceHeight + modifier),\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n fromBottom: ({\n center = false,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + targetHeight + modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n toLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + sourceWidth + modifier,\n height: _target_height,\n width: _target_width\n };\n },\n\n fromLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left - sourceWidth - modifier,\n height: _target_height,\n width: _target_width\n };\n },\n\n toRight: ({\n center = false,\n sourceWidth = _source_width,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + targetWidth - (sourceWidth + modifier),\n height: _target_height,\n width: _target_width\n };\n },\n\n fromRight: ({\n center = false,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + targetWidth + modifier,\n height: _target_height,\n width: _target_width\n };\n }\n };\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport * as classnames from '../../utils/classnames';\nimport * as css from '../../utils/css';\nimport * as styles from '../../utils/styles';\nimport { position } from './utils/position';\n\nexport const create = (text: string | number = '', tag = 'span') => {\n const _el = document.createElement(tag);\n const _text_content = document.createTextNode(text + '');\n\n _el.appendChild(_text_content);\n _el.setAttribute('title', text + 'px');\n classnames.set(_el, 'ph speccer spacing');\n\n return _el;\n};\n\nexport const element = async (targetEl: HTMLElement) => {\n if (!targetEl) return;\n\n const _target_styles = await styles.get(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n const _target_spacing_styles = css.getSpacing(_target_styles);\n const _target_pruned_spacing_styles = Object.keys(\n _target_spacing_styles\n ).filter((property) => {\n const _value = _target_spacing_styles[property];\n\n return _value !== '0px';\n });\n\n if (_target_pruned_spacing_styles.length === 0) return;\n\n _target_pruned_spacing_styles.forEach(async (property) => {\n const _value = css.getNumberValue(_target_spacing_styles[property]);\n const _speccer_el = create(_value);\n const _class_name = css.getClassNameFromCSSProperty(property);\n\n classnames.set(_speccer_el, _class_name);\n document.body.appendChild(_speccer_el);\n\n targetEl.classList.add('is-specced');\n await position(property, _value, _speccer_el, targetEl);\n });\n};\n","import * as styles from '../../../utils/styles';\nimport { offset } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\nexport const position = async (\n property: string,\n value: number,\n spacingEl: HTMLElement,\n targetEl: HTMLElement\n) => {\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _target_offset = await offset(targetEl);\n\n if (property === 'marginTop') {\n styles.add(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top - value + 'px'\n });\n }\n\n if (property === 'marginRight') {\n styles.add(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left + parseInt(_target_rect.width + '', 10) + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'marginBottom') {\n styles.add(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top + parseInt(_target_rect.height + '', 10) + 'px'\n });\n }\n\n if (property === 'marginLeft') {\n styles.add(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left - value + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingTop') {\n styles.add(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingBottom') {\n styles.add(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top:\n _target_offset.top +\n (parseInt(_target_rect.height + '', 10) - value) +\n 'px'\n });\n }\n\n if (property === 'paddingRight') {\n styles.add(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left:\n _target_offset.left +\n (parseInt(_target_rect.width + '', 10) - value) +\n 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingLeft') {\n styles.add(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n });\n }\n};\n","/* eslint-disable no-unused-vars */\n\n/**\n * Enum representing different areas in Speccer.\n */\nexport enum SpeccerAreaEnum {\n Empty = '', // Represents an empty area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom',// Represents the bottom area\n Top = 'top', // Represents the top area\n}\n\n/**\n * Enum representing different areas in Dissect.\n */\nexport enum DissectAreaEnum {\n Outline = 'outline', // Represents an outline area\n Enclose = 'enclose', // Represents an enclose area\n Full = 'full', // Represents a full area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom', // Represents the bottom area\n Top = 'top', // Represents the top area\n SVG = 'svg', // Represents an SVG area\n Curly = 'curly', // Represents a curly area\n}\n\n/**\n * Enum representing different measurement areas.\n */\nexport enum MeasureAreaEnum {\n Width = 'width', // Represents the width measurement area\n Height = 'height', // Represents the height measurement area\n Left = 'left', // Represents the left measurement area\n Right = 'right', // Represents the right measurement area\n Bottom = 'bottom', // Represents the bottom measurement area\n Top = 'top', // Represents the top measurement area\n}\n","import { DissectAreaEnum, MeasureAreaEnum } from 'types/enums/area';\n\n/**\n * Splits a string containing areas into an array of strings.\n *\n * @param areaString - The string containing areas.\n * @returns An array of area strings.\n *\n * @example\n * const areas = getAreasFromString('left right top');\n * // areas: ['left', 'right', 'top']\n */\nexport const getAreasFromString = (areaString: string): string[] =>\n areaString.split(' ');\n\n/**\n * Checks if 'left' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'left' is present, otherwise `false`.\n */\nexport const isLeftArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Left);\n};\n\n/**\n * Checks if 'right' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'right' is present, otherwise `false`.\n */\nexport const isRightArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Right);\n};\n\n/**\n * Checks if 'top' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'top' is present, otherwise `false`.\n */\nexport const isTopArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Top);\n};\n\n/**\n * Checks if 'bottom' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'bottom' is present, otherwise `false`.\n */\nexport const isBottomArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Bottom);\n};\n\n/**\n * Checks if 'full' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'full' is present, otherwise `false`.\n */\nexport const isFullArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Full);\n};\n\n/**\n * Checks if 'enclose' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'enclose' is present, otherwise `false`.\n */\nexport const isEncloseArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Enclose);\n};\n\n/**\n * Checks if 'height' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'height' is present, otherwise `false`.\n */\nexport const isHeightArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Height);\n};\n\n/**\n * Checks if 'width' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'width' is present, otherwise `false`.\n */\nexport const isWidthArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Width);\n};\n\n/**\n * Checks if the provided areaString contains SVG-related areas.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if any SVG-related area is present, otherwise `false`.\n */\nexport const useSVG = (areaString: string): boolean =>\n areaString.includes(DissectAreaEnum.SVG) ||\n areaString.includes(DissectAreaEnum.Curly) ||\n areaString.includes(DissectAreaEnum.Full) ||\n areaString.includes(DissectAreaEnum.Enclose);\n\n/**\n * Checks if the provided areaString contains 'curly' and 'full' areas.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if both 'curly' and 'full' are present, otherwise `false`.\n */\nexport const isCurly = (areaString: string): boolean =>\n areaString.includes(DissectAreaEnum.Curly) &&\n areaString.includes(DissectAreaEnum.Full);\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Generates a unique ID consisting of an underscore followed by a random alphanumeric string.\n *\n * @returns {string} - A unique ID.\n *\n * @example\n * // Generate a unique ID\n * const id = uniqueID();\n * console.log(id); // Example output: \"_abc123def\"\n */\nexport const uniqueID = (): string =>\n '_' + Math.random().toString(36).substring(2, 11);\n","/**\n * Coordinates object containing functions to retrieve specific coordinates from a DOMRect.\n */\nexport const coords = {\n top: (rect: DOMRect) => rect.top,\n right: (rect: DOMRect) => rect.left + rect.width,\n bottom: (rect: DOMRect) => rect.top + rect.height,\n left: (rect: DOMRect) => rect.left,\n center_x: (rect: DOMRect) => rect.left + rect.width / 2,\n center_y: (rect: DOMRect) => rect.top + rect.height / 2\n};\n","import { coords } from './coords';\n\n/**\n * Coordinates object containing functions to retrieve specific x and y coordinates from a DOMRect.\n */\nexport const xy = {\n center: (rect: DOMRect) => ({\n x: coords.center_x(rect),\n y: coords.center_y(rect)\n }),\n top: (rect: DOMRect) => ({ x: coords.center_x(rect), y: coords.top(rect) }),\n right: (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.center_y(rect)\n }),\n bottom: (rect: DOMRect) => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n left: (rect: DOMRect) => ({ x: coords.left(rect), y: coords.center_y(rect) }),\n 'right-top': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n 'right-bottom': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\n }),\n 'left-top': (rect: DOMRect) => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n 'left-bottom': (rect: DOMRect) => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n 'top-left': (rect: DOMRect) => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n 'top-right': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n 'bottom-left': (rect: DOMRect) => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n 'bottom-right': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\n }),\n 'top-center': (rect: DOMRect) => ({\n x: coords.center_x(rect),\n y: coords.top(rect)\n }),\n 'right-center': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.center_y(rect)\n }),\n 'bottom-center': (rect: DOMRect) => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n 'left-center': (rect: DOMRect) => ({\n x: coords.left(rect),\n y: coords.center_y(rect)\n })\n};\n","import { waitForFrame } from './wait';\nimport { xy } from './xy';\n\n/**\n * Get the intrinsic coordinates of an element based on a specified position.\n *\n * @param {HTMLElement} el - The HTML element.\n * @param {string} [pos='center'] - The position to use.\n * @throws {Error} No position given.\n * @throws {Error} The position given is not the required type.\n * @returns {Promise<{ x: number, y: number }>} - An object containing the coordinates.\n * @example\n * // Get intrinsic coordinates for an element\n * const element = document.getElementById('example');\n * const coordinates = await intrinsic_coords(element, 'top-left');\n */\nexport const intrinsic_coords = async (\n el: HTMLElement,\n pos = 'center'\n): Promise<{ x: number; y: number }> => {\n if (!pos) {\n throw new Error('No position given');\n }\n\n if (typeof pos !== 'string') {\n throw new Error(\n `The position given is not the required type: pos: ${typeof pos}`\n );\n }\n\n const _allowed_positions = [\n 'center',\n 'left',\n 'right',\n 'top',\n 'bottom',\n 'right-top',\n 'right-bottom',\n 'left-top',\n 'left-bottom',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n 'top-center',\n 'right-center',\n 'bottom-center',\n 'left-center'\n ];\n\n if (!_allowed_positions.includes(pos)) {\n throw new Error(\n `The position given does not match allowed positions to use! Valid positions are: ${_allowed_positions.join(\n ', '\n )}`\n );\n }\n\n await waitForFrame();\n\n const _el_rect = el.getBoundingClientRect();\n\n return xy[pos](_el_rect);\n};\n","import { intrinsic_coords } from './intrinsic-coords';\n\n/**\n * Get the x and y coordinates of two elements and return them as an object.\n *\n * @param {HTMLElement} el1 - The first HTML element.\n * @param {HTMLElement} el2 - The second HTML element.\n * @param {string} [pos1='center'] - The position to use for the first element.\n * @param {string} [pos2='center'] - The position to use for the second element.\n * @throws {Error} No element given.\n * @returns {Promise<{ x1: number, y1: number, x2: number, y2: number }>} - An object containing the coordinates.\n * @example\n * // Get coordinates for two elements\n * const element1 = document.getElementById('element1');\n * const element2 = document.getElementById('element2');\n * const coordinates = await get_coords_pair_from_objects(element1, element2);\n */\nexport const getCoordsPairFromObjects = async (\n el1: HTMLElement,\n el2: HTMLElement,\n pos1 = 'center',\n pos2 = 'center'\n): Promise<{ x1: number; y1: number; x2: number; y2: number }> => {\n if (!el1 || !el2) {\n throw new Error('No element given');\n }\n\n const { x: x1, y: y1 } = await intrinsic_coords(el1, pos1);\n const { x: x2, y: y2 } = await intrinsic_coords(el2, pos2);\n\n return {\n x1,\n y1,\n x2,\n y2\n };\n};\n","import {\n BezierPathOptionsType,\n CreateCoordinatesForCurveCoordParamType,\n CreateCoordinatesForCurveOptionsParamType,\n CurlyBezierPathOptionsType\n} from 'types/bezier';\nimport { getCoordsPairFromObjects } from './get-coords-pair-from-objects';\n\n/**\n * Calculates coordinates for a Bezier curve between two points.\n *\n * @param coords - The coordinates of the start and end points.\n * @param options - Options for controlling the curve's shape.\n * @returns Coordinates for the Bezier curve.\n *\n * @example\n * const coordinates = createBezierCurveCoordinates(\n * { x1: 0, x2: 100, y1: 0, y2: 100 },\n * { direct: true, firstSet: true, direction: 'west' }\n * );\n */\nexport const createBezierCurveCoordinates = (\n coords: CreateCoordinatesForCurveCoordParamType,\n options: CreateCoordinatesForCurveOptionsParamType\n) => {\n const { x1, x2, y1, y2 } = coords;\n const { direct = false, firstSet = false, direction } = options;\n const firstPoint = { x: x1, y: y1 }; // The first point of the curve\n const lastPoint = { x: x2, y: y2 }; // The last point of the curve\n\n let firstControl = { x: x1 + (x2 - x1) / 2, y: y1 }; // Control point for the first point\n let lastControl = { x: x1 + (x2 - x1) / 2, y: y2 }; // Control point for the last point\n\n if (direct) {\n if (firstSet) {\n if (direction === 'west') {\n firstControl = { x: x1 - 32, y: y1 - 16 / 2 };\n lastControl = { x: x2 + 32, y: y2 };\n } else if (direction === 'south') {\n firstControl = { x: x1 - 16 / 2, y: y1 + 32 };\n lastControl = { x: x2, y: y2 - 32 };\n } else if (direction === 'east') {\n firstControl = { x: x1 + 32, y: y1 - 16 / 2 };\n lastControl = { x: x2 - 32, y: y2 };\n } else {\n firstControl = { x: x1 - 16 / 2, y: y1 - 32 };\n lastControl = { x: x2, y: y2 + 32 };\n }\n } else {\n if (direction === 'west') {\n firstControl = { x: x1 - 32, y: y1 + 16 / 2 };\n lastControl = { x: x2 + 32, y: y2 };\n } else if (direction === 'south') {\n firstControl = { x: x1 + 16 / 2, y: y1 + 32 };\n lastControl = { x: x2, y: y2 - 32 };\n } else if (direction === 'east') {\n firstControl = { x: x1 + 32, y: y1 + 16 / 2 };\n lastControl = { x: x2 - 32, y: y2 };\n } else {\n firstControl = { x: x1 + 16 / 2, y: y1 - 32 };\n lastControl = { x: x2, y: y2 + 32 };\n }\n }\n }\n\n return {\n firstPoint,\n firstControl,\n lastPoint,\n lastControl\n };\n};\n\n/**\n * Generates an SVG path for a curved line between two HTML elements.\n *\n * @param startEl - The starting HTML element.\n * @param stopEl - The ending HTML element.\n * @param options - Options for controlling the curved line.\n * @returns The SVG path string for the curved line.\n *\n * @example\n * const svgPath = getCurlySVGPath(startElement, stopElement, {\n * pos1: 'top',\n * pos2: 'bottom',\n * firstSet: true,\n * direction: 'south',\n * });\n */\nexport const getCurlySVGPath = async (\n startEl: HTMLElement,\n stopEl: HTMLElement,\n options: CurlyBezierPathOptionsType\n) => {\n const { pos1, pos2, firstSet = false, direction } = options;\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(\n startEl,\n stopEl,\n pos1,\n pos2\n );\n const x1modifier = 0;\n const y1modifier = 0;\n\n let x2modifier = 0;\n let y2modifier = 0;\n\n // Create a gap between the pin and the bracket center\n if (direction == 'north') {\n y2modifier = 8;\n } else if (direction == 'west') {\n x2modifier = 8;\n } else if (direction == 'east') {\n x2modifier = -8;\n } else if (direction == 'south') {\n y2modifier = -8;\n }\n\n const coordinates = createBezierCurveCoordinates(\n {\n x1: x1 + x1modifier,\n x2: x2 + x2modifier,\n y1: y1 + y1modifier,\n y2: y2 + y2modifier\n },\n {\n direct: true,\n firstSet,\n direction\n }\n );\n const { firstPoint, firstControl, lastControl, lastPoint } = coordinates;\n\n return (\n `M ${firstPoint.x} ${firstPoint.y}` +\n `C ${firstControl.x} ${firstControl.y}, ${lastControl.x} ${lastControl.y}, ${lastPoint.x} ${lastPoint.y}`\n );\n};\n\n/**\n * Generates an SVG path for a straight line between two HTML elements.\n *\n * @param startEl - The starting HTML element.\n * @param stopEl - The ending HTML element.\n * @param options - Options for controlling the straight line.\n * @returns The SVG path string for the straight line.\n *\n * @example\n * const svgPath = getSVGPath(startElement, stopElement, {\n * pos1: 'left',\n * pos2: 'right',\n * });\n */\nexport const getSVGPath = async (\n startEl: HTMLElement,\n stopEl: HTMLElement,\n options: BezierPathOptionsType\n) => {\n const { pos1, pos2 } = options;\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(\n startEl,\n stopEl,\n pos1,\n pos2\n );\n const coordinates = createBezierCurveCoordinates(\n { x1, x2, y1, y2 },\n { direction: '' }\n );\n const { firstPoint, firstControl, lastControl, lastPoint } = coordinates;\n\n return (\n `M ${firstPoint.x} ${firstPoint.y}` +\n `C ${firstControl.x} ${firstControl.y}, ${lastControl.x} ${lastControl.y}, ${lastPoint.x} ${lastPoint.y}`\n );\n};\n\n/**\n * Returns positions for creating an SVG path based on a cardinal direction.\n *\n * @param direction - The cardinal direction ('east', 'west', 'south', 'north').\n * @returns Positions for creating an SVG path.\n *\n * @example\n * const positions = getPositionsForSVGPath('east');\n */\nexport const getPositionsForSVGPath = (direction: string) => {\n let pos1: string;\n let pos2: string;\n\n switch (direction) {\n case 'east':\n pos1 = 'right';\n pos2 = 'left';\n break;\n case 'south':\n pos1 = 'bottom';\n pos2 = 'top';\n break;\n case 'west':\n pos1 = 'left';\n pos2 = 'right';\n break;\n case 'north':\n default:\n pos1 = 'top';\n pos2 = 'bottom';\n break;\n }\n\n return { pos1, pos2 };\n};\n\n/**\n * Returns positions for creating an SVG path for a curved line based on a cardinal direction.\n *\n * @param direction - The cardinal direction ('east', 'west', 'south', 'north').\n * @returns Positions for creating an SVG path for a curved line.\n *\n * @example\n * const positions = getPositionsForCurlySVGPath('west');\n */\nexport const getPositionsForCurlySVGPath = (direction: string) => {\n let path1pos1: string;\n let path1pos2: string;\n let path2pos1: string;\n let path2pos2: string;\n\n switch (direction) {\n case 'east':\n path1pos1 = 'right-top';\n path1pos2 = 'left-center';\n path2pos1 = 'right-bottom';\n path2pos2 = 'left-center';\n break;\n case 'south':\n path1pos1 = 'bottom-left';\n path1pos2 = 'top-center';\n path2pos1 = 'bottom-right';\n path2pos2 = 'top-center';\n break;\n case 'west':\n path1pos1 = 'left-top';\n path1pos2 = 'right-center';\n path2pos1 = 'left-bottom';\n path2pos2 = 'right-center';\n break;\n case 'north':\n default:\n path1pos1 = 'top-left';\n path1pos2 = 'bottom-center';\n path2pos1 = 'top-right';\n path2pos2 = 'bottom-center';\n break;\n }\n\n return {\n path1pos1,\n path1pos2,\n path2pos1,\n path2pos2\n };\n};\n","import { angle } from './angle';\nimport { cardinal_direction, cardinal_direction_crude } from './cardinal';\nimport { getCoordsPairFromObjects } from './get-coords-pair-from-objects';\n\n/**\n * Get the direction of an element based on its position relative to another element.\n *\n * @param {Object} options - Options for direction calculation.\n * @param {HTMLElement} options.start - The starting HTML element.\n * @param {HTMLElement} options.stop - The stopping HTML element.\n * @param {boolean} [options.crude=false] - If the direction should be calculated crudely (NSEW).\n * @returns {Promise<string>} - The calculated direction.\n * @example\n * // Get the direction of one element relative to another\n * const startElement = document.getElementById('startElement');\n * const stopElement = document.getElementById('stopElement');\n * const direction = await direction_of_element({ start: startElement, stop: stopElement });\n */\nexport const direction_of_element = async ({\n start,\n stop,\n crude = false\n}: {\n start: HTMLElement;\n stop: HTMLElement;\n crude?: boolean;\n}): Promise<string> => {\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(start, stop);\n const _angle = angle(x1, y1, x2, y2);\n const _direction = crude\n ? cardinal_direction_crude(_angle)\n : cardinal_direction(_angle);\n\n return _direction;\n};\n","/**\n * Returns the angle between two sets of coordinates.\n *\n * @param {number} cx - The x-coordinate of the first point.\n * @param {number} cy - The y-coordinate of the first point.\n * @param {number} ex - The x-coordinate of the second point.\n * @param {number} ey - The y-coordinate of the second point.\n * @param {boolean} [normalize=true] - If the angle output should be normalized to a value between 0° and 360°.\n * @throws {SyntaxError} Missing input for `angle`.\n * @throws {TypeError} Parameters for `angle` do not have the required type.\n * @returns {number} The angle between the given coordinates.\n * @example\n * // Calculate the angle between two points\n * const angleValue = angle(0, 0, 3, 4);\n */\nexport const angle = (\n cx: number,\n cy: number,\n ex: number,\n ey: number,\n normalize = true\n): number => {\n if (!cx || !cy || !ex || !ey) {\n throw new SyntaxError('Missing input for `angle`');\n }\n\n if (\n typeof cx !== 'number' ||\n typeof cy !== 'number' ||\n typeof ex !== 'number' ||\n typeof ey !== 'number'\n ) {\n throw new TypeError(\n `Parameters for \\`angle\\` do not have the required type. Requires number! Got: ${typeof cx} ${typeof cy} ${typeof ex} ${typeof ey}`\n );\n }\n\n const dy = ey - cy;\n const dx = ex - cx;\n\n let theta = Math.atan2(dy, dx); // range (-PI, PI]\n\n theta *= 180 / Math.PI; // radians to degrees, range (-180, 180]\n\n if (normalize && theta < 0) theta = 360 + theta; // range [0, 360)\n\n return theta;\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Gives you the cardinal direction based on degrees.\n * Note: The degrees start at 0, which is EAST (originally, north should be 0, but here, north is 270),\n * and we travel clockwise.\n *\n * @param {number} degrees - The angle in degrees.\n * @throws {RangeError} Parameter cannot exceed 360.\n * @throws {RangeError} Parameter cannot be lower than 0.\n * @returns {string} - The cardinal direction.\n * @example\n * // Get the cardinal direction for an angle in degrees\n * const direction = cardinal_direction(45);\n */\nexport const cardinal_direction = (degrees: number): string => {\n if (degrees > 360) throw new RangeError('Parameter cannot exceed 360');\n\n if (degrees < 0) throw new RangeError('Parameter cannot be lower than 0');\n\n if (degrees >= 0 && degrees <= 22.5) {\n return 'east';\n } else if (degrees >= 22.5 && degrees <= 67.5) {\n return 'south-east';\n } else if (degrees >= 67.5 && degrees <= 112.5) {\n return 'south';\n } else if (degrees >= 112.5 && degrees <= 157.5) {\n return 'south-west';\n } else if (degrees >= 157.5 && degrees <= 202.5) {\n return 'west';\n } else if (degrees >= 202.5 && degrees <= 247.5) {\n return 'north-west';\n } else if (degrees >= 247.5 && degrees <= 292.5) {\n return 'north';\n } else if (degrees >= 292.5 && degrees <= 337.5) {\n return 'north-east';\n } else {\n return 'east';\n }\n};\n\n/**\n * Gives you the cardinal direction based on degrees (crude version).\n * Note: The degrees start at 0, which is EAST (originally, north should be 0, but here, north is 270),\n * and we travel clockwise.\n *\n * @param {number} degrees - The angle in degrees.\n * @throws {RangeError} Parameter cannot exceed 360.\n * @throws {RangeError} Parameter cannot be lower than 0.\n * @returns {string} - The cardinal direction (NSEW).\n * @example\n * // Get the cardinal direction (crude) for an angle in degrees\n * const direction = cardinal_direction_crude(45);\n */\nexport const cardinal_direction_crude = (degrees: number): string => {\n if (degrees > 360) throw new RangeError('Parameter cannot exceed 360');\n\n if (degrees < 0) throw new RangeError('Parameter cannot be lower than 0');\n\n if (degrees >= 45 && degrees <= 135) {\n return 'south';\n } else if (degrees > 135 && degrees <= 225) {\n return 'west';\n } else if (degrees > 225 && degrees <= 315) {\n return 'north';\n } else if (degrees > 315) {\n return 'east';\n } else {\n return 'east';\n }\n};\n","'use strict';\n\nimport { uniqueID } from '../id';\nimport { getPositionsForSVGPath, getSVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\n\n/**\n * Class representing a DrawSVGLine instance.\n */\nexport class DrawSVGLine {\n #canvas: HTMLElement | SVGElement | null;\n #originalPathElement: HTMLElement | SVGPathElement | null;\n startElement: HTMLElement;\n stopElement: HTMLElement;\n line: SVGPathElement;\n\n /**\n * Creates a new DrawSVGLine instance.\n * @param startElement - The starting element for the line.\n * @param stopElement - The ending element for the line.\n */\n constructor(startElement: HTMLElement, stopElement: HTMLElement) {\n this.#init(startElement, stopElement);\n }\n\n /**\n * Initializes the DrawSVGLine instance.\n * @param startElement - The starting element for the line.\n * @param stopElement - The ending element for the line.\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(startElement: HTMLElement, stopElement: HTMLElement) {\n if (!startElement || !stopElement) {\n throw new Error('Missing inputs startElement and stopElement');\n }\n\n if (!document.body.contains(stopElement)) {\n throw new Error('stopElement is not in the DOM');\n }\n\n if (!document.body.contains(startElement)) {\n throw new Error('startElement is not in the DOM');\n }\n\n this.startElement = startElement;\n this.stopElement = stopElement;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n this.#originalPathElement = document.getElementById('ph-speccer-path');\n\n if (!this.#originalPathElement || !this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw lines. Please see the documentation'\n );\n }\n\n this.connect();\n }\n\n /**\n * Connects and draws the line.\n */\n connect() {\n this.draw(this.#originalPathElement as SVGPathElement);\n }\n\n /**\n * Draws the line based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n */\n async draw(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to draw!');\n }\n\n const _id = uniqueID();\n const _path_el_id = `ph_draw_path-path-${_id}`;\n const _new_path = path.cloneNode(false) as SVGPathElement;\n\n _new_path.setAttribute('id', _path_el_id);\n _new_path.setAttribute(\n 'data-start-el',\n this.startElement.getAttribute('id') || 'no-id-found'\n );\n _new_path.classList.remove('original');\n _new_path.classList.add('speccer');\n\n if (path.parentNode) {\n this.line = path.parentNode.insertBefore(_new_path, path.nextSibling);\n } else {\n throw new Error('No parentNode found for path');\n }\n\n const _direction = await direction_of_element({\n start: this.startElement,\n stop: this.stopElement,\n crude: true\n });\n const { pos1, pos2 } = getPositionsForSVGPath(_direction);\n const _d = await getSVGPath(this.startElement, this.stopElement, {\n pos1,\n pos2\n });\n\n this.line.setAttribute('data-direction', _direction);\n this.line.setAttribute('data-pos1', pos1);\n this.line.setAttribute('data-pos2', pos2);\n\n this.line.setAttribute('d', _d); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawSVGLine = DrawSVGLine;\n","'use strict';\n\nimport { uniqueID } from '../id';\nimport { getCurlySVGPath, getPositionsForCurlySVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\n\n/**\n * Class representing a DrawSVGCurlyBracket instance.\n */\nexport class DrawSVGCurlyBracket {\n #canvas: HTMLElement | SVGElement | null;\n #originalPathElement: HTMLElement | SVGPathElement | null;\n startElement: HTMLElement;\n stopElement: HTMLElement;\n firstPathElement: SVGPathElement;\n secondPathElement: SVGPathElement;\n\n /**\n * Creates a new DrawSVGCurlyBracket instance.\n * @param startElement - The starting element for the bracket.\n * @param stopElement - The ending element for the bracket.\n */\n constructor(startElement: HTMLElement, stopElement: HTMLElement) {\n this.#init(startElement, stopElement);\n }\n\n /**\n * Initializes the DrawSVGCurlyBracket instance.\n * @param startElement - The starting element for the bracket.\n * @param stopElement - The ending element for the bracket.\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(startElement: HTMLElement, stopElement: HTMLElement) {\n if (!startElement || !stopElement) {\n throw new Error('Missing inputs startElement and stopElement');\n }\n\n if (!document.body.contains(stopElement)) {\n throw new Error('stopElement is not in the DOM');\n }\n\n if (!document.body.contains(startElement)) {\n throw new Error('startElement is not in the DOM');\n }\n\n this.startElement = startElement;\n this.stopElement = stopElement;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n this.#originalPathElement = document.getElementById('ph-speccer-path');\n\n if (!this.#originalPathElement || !this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw lines. Please see the documentation'\n );\n }\n\n this.connect();\n }\n\n /**\n * Connects and draws the curly bracket.\n */\n connect() {\n this.draw(this.#originalPathElement as SVGPathElement);\n }\n\n /**\n * Creates a new path element based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n * @returns A new SVGPathElement.\n */\n #getPathElement(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to #getPathElement!');\n }\n\n const _id = uniqueID();\n const _path_el_id = `ph_draw_path-path-${_id}`;\n const _new_path = path.cloneNode(false) as SVGPathElement;\n\n _new_path.setAttribute(\n 'data-start-el',\n this.startElement.getAttribute('id') || 'no-id-found'\n );\n _new_path.setAttribute('id', _path_el_id);\n _new_path.classList.remove('original');\n _new_path.classList.add('speccer');\n\n return _new_path;\n }\n\n /**\n * Draws the curly bracket based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n */\n async draw(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to draw!');\n }\n\n const _first_path_element = this.#getPathElement(path);\n const _second_path_element = this.#getPathElement(path);\n\n if (path.parentNode) {\n this.firstPathElement = path.parentNode.insertBefore(\n _first_path_element,\n path.nextSibling\n );\n this.secondPathElement = path.parentNode.insertBefore(\n _second_path_element,\n path.nextSibling\n );\n } else {\n throw new Error('No parentNode found for path');\n }\n\n const _direction = await direction_of_element({\n stop: this.stopElement,\n start: this.startElement,\n crude: true\n });\n const { path1pos1, path1pos2, path2pos1, path2pos2 } =\n getPositionsForCurlySVGPath(_direction);\n const _first_path_d = await getCurlySVGPath(\n this.startElement,\n this.stopElement,\n {\n pos1: path1pos1,\n pos2: path1pos2,\n firstSet: true,\n direction: _direction\n }\n );\n const _second_path_d = await getCurlySVGPath(\n this.startElement,\n this.stopElement,\n {\n pos1: path2pos1,\n pos2: path2pos2,\n direction: _direction\n }\n );\n\n this.firstPathElement.setAttribute('data-direction', _direction);\n this.firstPathElement.setAttribute('data-pos1', path1pos1);\n this.firstPathElement.setAttribute('data-pos2', path1pos2);\n this.firstPathElement.setAttribute('d', _first_path_d); // SVG attributes\n this.secondPathElement.setAttribute('data-direction', _direction);\n this.secondPathElement.setAttribute('data-pos1', path2pos1);\n this.secondPathElement.setAttribute('data-pos2', path2pos2);\n this.secondPathElement.setAttribute('d', _second_path_d); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawSVGCurlyBracket = DrawSVGCurlyBracket;\n","import * as css from '../../../utils/css';\nimport * as position from '../../../utils/position';\nimport {\n isBottomArea,\n isEncloseArea,\n isFullArea,\n isLeftArea,\n isRightArea\n} from '../../../utils/area';\nimport { DissectStylesOptionsType } from 'types/bezier';\n\nexport const styles = async (\n area: string,\n targetEl: HTMLElement,\n dissectionEl: HTMLElement,\n options?: DissectStylesOptionsType\n) => {\n const { isCurly = false } = options || {};\n const SPECCER_PIN_SPACE = css.pinSpace(dissectionEl);\n const SPECCER_MEASURE_SIZE = css.measureSize(dissectionEl);\n const _positional_styles = await position.getRec(dissectionEl, targetEl);\n\n if (isEncloseArea(area)) {\n const { left, top, height, width } = _positional_styles.absolute();\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n }\n\n if (isLeftArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, height } = _positional_styles.fromLeft({\n sourceWidth: SPECCER_MEASURE_SIZE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n };\n } else {\n const { left, top } = _positional_styles.fromLeft({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else if (isRightArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, height } = _positional_styles.fromRight({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n };\n } else {\n const { left, top } = _positional_styles.fromRight({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else if (isBottomArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, width } = _positional_styles.fromBottom({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n };\n } else {\n const { left, top } = _positional_styles.fromBottom({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else {\n if (isFullArea(area) && !isCurly) {\n const { left, top, width } = _positional_styles.fromTop({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n };\n } else {\n const { left, top } = _positional_styles.fromTop({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { DissectAreaEnum } from '../../types/enums/area';\n\nimport * as classnames from '../../utils/classnames';\nimport { SPECCER_LITERALS } from '../../utils/constants';\nimport { add } from '../../utils/styles';\nimport { isCurly, isEncloseArea, isFullArea, useSVG } from '../../utils/area';\nimport { DrawSVGLine } from '../../utils/classes/DrawSVGLine';\nimport { DrawSVGCurlyBracket } from '../../utils/classes/DrawSVGCurlyBracket';\n\nimport { styles } from './utils/styles';\n\nexport const create = (textContent = '', area: string, n = 'span') => {\n const _el = document.createElement(n);\n const _text_node = document.createTextNode(textContent);\n const _extra_class_names = {};\n\n if (area !== null && area !== '') {\n _extra_class_names[area] = true;\n }\n\n if (\n (!isFullArea(area) && !isEncloseArea(area)) ||\n (isFullArea(area) && isCurly(area))\n ) {\n _el.appendChild(_text_node);\n } else if (isFullArea(area) || isEncloseArea(area)) {\n _el.setAttribute('data-dissection-counter', textContent);\n }\n\n const _class_names = classnames.cx(\n 'ph speccer dissection',\n _extra_class_names\n );\n\n classnames.set(_el, _class_names);\n\n return _el;\n};\n\nexport const element = (sectionEl: HTMLElement) => {\n if (!sectionEl) return;\n\n const _dissection_els = sectionEl.querySelectorAll('[data-anatomy]');\n\n if (_dissection_els) {\n let _index_to_use = 0;\n\n _dissection_els.forEach(async (targetEl: HTMLElement, targetIndex) => {\n if (!targetEl) return Promise.resolve();\n\n const _areas_string: string = targetEl.getAttribute('data-anatomy') || '';\n\n if (\n !_areas_string ||\n _areas_string === '' ||\n _areas_string.indexOf(DissectAreaEnum.Outline) === -1\n )\n return;\n\n /**\n * If we're running out of literals to use,\n * make a new one with uppercase and lower case pairs\n */\n let _literal_to_use = SPECCER_LITERALS[targetIndex];\n\n if (!_literal_to_use) {\n _literal_to_use = `${SPECCER_LITERALS[_index_to_use]}${SPECCER_LITERALS[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n const _dissection_el = create(_literal_to_use, _areas_string);\n\n document.body.appendChild(_dissection_el);\n\n const _dissection_styles = await styles(\n _areas_string,\n targetEl,\n _dissection_el,\n {\n isCurly: isCurly(_areas_string)\n }\n );\n\n await add(_dissection_el, _dissection_styles);\n\n if (useSVG(_areas_string)) {\n new DrawSVGLine(targetEl, _dissection_el);\n } else if (isCurly(_areas_string)) {\n new DrawSVGCurlyBracket(targetEl, _dissection_el);\n }\n });\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport {\n isBottomArea,\n isHeightArea,\n isRightArea,\n isWidthArea\n} from 'utils/area';\nimport * as classnames from '../../utils/classnames';\nimport * as styles from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\nimport * as position from '../../utils/position';\nimport { SPECCER_DEFAULT_MEASURE_SIZE_NEG } from 'utils/constants';\n\nconst create = (\n text: string | number = '',\n area: string | null = '',\n tag = 'span'\n) => {\n const _el = document.createElement(tag);\n\n _el.setAttribute('title', text + 'px');\n _el.setAttribute('data-measure', parseInt(text + '', 10) + 'px');\n\n classnames.set(_el, `ph speccer measure ${area}`);\n\n return _el;\n};\n\nexport const element = async (targetEl: HTMLElement) => {\n if (!targetEl) return;\n\n const _areas_string: string | null = targetEl.getAttribute(\n 'data-speccer-measure'\n );\n\n if (_areas_string === '' || !_areas_string) {\n return;\n }\n\n const _target_styles = await styles.get(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n\n if (isWidthArea(_areas_string)) {\n if (isBottomArea(_areas_string)) {\n const _measure_el = create(_target_rect.width, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await position.getRec(_measure_el, targetEl);\n const { left, top, width } = _positional_styles.fromBottom({\n center: false\n });\n\n await styles.add(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n });\n } else {\n const _measure_el = create(_target_rect.width, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await position.getRec(_measure_el, targetEl);\n const { left, top, width } = _positional_styles.fromTop({\n center: false,\n modifier: SPECCER_DEFAULT_MEASURE_SIZE_NEG\n });\n\n await styles.add(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n });\n }\n } else if (isHeightArea(_areas_string)) {\n if (isRightArea(_areas_string)) {\n const _measure_el = create(_target_rect.height, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await position.getRec(_measure_el, targetEl);\n const { left, top, height } = _positional_styles.fromRight({\n center: false\n });\n\n await styles.add(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n });\n } else {\n const _measure_el = create(_target_rect.height, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await position.getRec(_measure_el, targetEl);\n const { left, top, height } = _positional_styles.fromLeft({\n center: false,\n modifier: SPECCER_DEFAULT_MEASURE_SIZE_NEG\n });\n\n await styles.add(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n });\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport * as styles from '../../utils/styles';\nimport { cx, set } from '../../utils/classnames';\nimport { getRec } from '../../utils/position';\n\nexport const create = (n = 'span') => {\n const markElement = document.createElement(n);\n const classNames = cx('ph speccer mark');\n\n set(markElement, classNames);\n\n return markElement;\n};\n\nexport const element = async (elementToMark: HTMLElement) => {\n if (!elementToMark) return Promise.resolve();\n\n const markElement = create();\n\n document.body.appendChild(markElement);\n\n const positionalStyles = await getRec(markElement, elementToMark);\n const { left, top, height, width } = positionalStyles.absolute();\n const markStyles = {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n\n await styles.add(markElement, markStyles);\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Converts a number to a string with a specified number of decimal places.\n *\n * @param {string | number} number - The number to convert.\n * @param {number} decimals - The number of decimal places (default is 3).\n * @returns {string} - The formatted number as a string.\n *\n * @example\n * // Convert a number to a string with 2 decimal places\n * const formattedNumber = decimal(12.3456, 2); // \"12.34\"\n */\nexport const decimal = (number: string | number, decimals = 3): string =>\n parseFloat(number + '').toFixed(decimals);\n","/* eslint no-console:0 */\n'use strict';\n\nimport * as classnames from '../../utils/classnames';\nimport * as styles from '../../utils/styles';\nimport { position } from './utils/position';\nimport { template } from './utils/template';\n\nexport const create = (html: string, area: string | null) => {\n const _el = document.createElement('div');\n const _extra_class_names = {};\n\n if (area !== null && area !== '') {\n _extra_class_names[area] = true;\n }\n\n const _class_names = classnames.cx(\n 'ph speccer typography',\n _extra_class_names\n );\n\n _el.innerHTML = html;\n\n classnames.set(_el, _class_names);\n\n return _el;\n};\n\nexport const element = async (targetEl: HTMLElement) => {\n if (!targetEl) return;\n\n const _area: string | null = targetEl.getAttribute('data-speccer-typography');\n const _target_styles = await styles.get(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n targetEl.classList.add('is-specced');\n\n const _html = await template(targetEl);\n const _speccer_el = create(_html, _area);\n\n document.body.appendChild(_speccer_el);\n\n const _position = await position(_area, targetEl, _speccer_el);\n\n styles.add(_speccer_el, _position);\n};\n","/* eslint @typescript-eslint/no-explicit-any: [\"error\", { \"fixToUnknown\": true }] */\n'use strict';\n\nimport { DebounceAnyFunctionType } from 'types/debounce';\n\n/**\n * Creates a debounced version of a function that delays its execution until after a specified waiting time has elapsed since the last time the debounced function was invoked.\n *\n * @param {DebounceAnyFunctionType} func - The function to debounce.\n * @param {number} wait - The number of milliseconds to wait before invoking the function after the last call.\n * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately after the first call.\n * @returns {DebounceAnyFunctionType} - The debounced function.\n *\n * @example\n * // Create a debounced function\n * const debouncedFn = debounce((value) => {\n * console.log(value);\n * }, 500);\n *\n * // Call the debounced function\n * debouncedFn('Hello'); // This will not trigger immediate execution\n * debouncedFn('World'); // This will trigger immediate execution\n */\nconst debounce = (\n func: DebounceAnyFunctionType,\n wait: number,\n immediate = false\n): DebounceAnyFunctionType => {\n let timeout: null | ReturnType<typeof setTimeout>;\n\n return function (context: unknown, ...args: unknown[]): void {\n const later = function (): void {\n timeout = null;\n\n if (!immediate) func.apply(context, args);\n };\n const callNow = immediate && !timeout;\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(later, wait);\n\n if (callNow) func.apply(context, args);\n };\n};\n\nexport default debounce;\n","'use strict';\n\nimport { SpeccerFunctionType } from 'types/speccer';\n\nimport debounce from './debounce';\n\n/**\n * Attaches a debounced event listener to the window's resize event that triggers the provided function.\n *\n * @param {SpeccerFunctionType} speccer - The function to trigger when the window is resized.\n *\n * @example\n * // Define a function to be triggered on window resize\n * const mySpeccer = () => {\n * // Your logic here\n * console.log('Window resized');\n * };\n *\n * // Activate the debounced event listener\n * activate(mySpeccer);\n */\nexport const activate = (speccer: SpeccerFunctionType): void => {\n /**\n * The debounced event listener function.\n * @type {Function}\n */\n const speccerEventFunc = () =>\n debounce(() => {\n speccer();\n }, 300);\n\n // Remove any existing resize event listeners to prevent duplicates\n window.removeEventListener('resize', speccerEventFunc);\n\n // Add the debounced resize event listener\n window.addEventListener('resize', speccerEventFunc);\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { SpeccerFunctionType } from 'types/speccer';\n\nimport * as resize from '../utils/resize';\n\nimport * as spec from '../features/spacing';\nimport * as measure from '../features/measure';\nimport * as dissect from '../features/dissect';\n\nexport const dom = (speccer: SpeccerFunctionType) => {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n speccer();\n });\n } else {\n // `DOMContentLoaded` already fired\n speccer();\n }\n};\n\nexport const lazy = () => {\n const _spec_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el: IntersectionObserverEntry) => {\n if (el.intersectionRatio > 0) {\n spec.element(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document\n .querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n )\n .forEach((el) => {\n _spec_observer.observe(el);\n });\n\n const _measure_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el) => {\n if (el.intersectionRatio > 0) {\n measure.element(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document.querySelectorAll('[data-speccer-measure]').forEach((el) => {\n _measure_observer.observe(el);\n });\n\n const _dissect_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el) => {\n if (el.intersectionRatio > 0) {\n dissect.element(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document.querySelectorAll('[data-anatomy-section]').forEach((el) => {\n _dissect_observer.observe(el);\n });\n};\n\nexport const manual = (speccer: SpeccerFunctionType) => {\n window.speccer = speccer;\n};\n\nexport const activate = (speccer: SpeccerFunctionType) => {\n const _script = document.currentScript;\n\n if (_script) {\n const _speccer_script_src = _script.getAttribute('src');\n\n if (\n _speccer_script_src &&\n (_speccer_script_src.indexOf('speccer.js') !== -1 ||\n // for codepen\n _speccer_script_src.indexOf('JaXpOK.js') !== -1)\n ) {\n if (_script.hasAttribute('data-manual')) {\n manual(speccer);\n } else if (_script.hasAttribute('data-instant')) {\n speccer();\n } else if (_script.hasAttribute('data-dom')) {\n dom(speccer);\n } else if (_script.hasAttribute('data-lazy')) {\n lazy();\n } else {\n dom(speccer);\n }\n\n if (\n !_script.hasAttribute('data-manual') &&\n !_script.hasAttribute('data-lazy')\n ) {\n resize.activate(speccer);\n }\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport './types/interfaces/global';\nimport * as node from './utils/node';\nimport * as __spacing from './features/spacing';\nimport * as __dissect from './features/dissect';\nimport * as __measure from './features/measure';\nimport * as __mark from './features/mark';\nimport * as __typography from './features/typography';\nimport * as browser from './config/browser';\n\nexport const spacing = __spacing;\n\nexport const dissect = __dissect;\n\nexport const measure = __measure;\n\nexport const mark = __mark;\n\nexport const typography = __typography;\n\nexport const modes = browser;\n\nconst speccer = () => {\n node.removeAll('.speccer');\n\n const _els_to_be_specced = document.querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n );\n const _els_to_be_measured = document.querySelectorAll(\n '[data-speccer-measure]'\n );\n const _els_to_be_typography_specced = document.querySelectorAll(\n '[data-speccer-typography]'\n );\n const _els_to_be_dissected = document.querySelectorAll(\n '[data-anatomy-section]'\n );\n const _els_to_be_marked = document.querySelectorAll('[data-speccer-mark]');\n\n _els_to_be_marked.forEach(mark.element);\n _els_to_be_specced.forEach(spacing.element);\n _els_to_be_measured.forEach(measure.element);\n _els_to_be_typography_specced.forEach(typography.element);\n _els_to_be_dissected.forEach(dissect.element);\n};\n\nexport default speccer;\n\nbrowser.activate(speccer);\n","import * as css from '../../../utils/css';\nimport * as styles from '../../../utils/styles';\n\nexport const template = async (targetEl: HTMLElement): Promise<string> => {\n const _target_styles = await styles.get(targetEl);\n const _styles = css.getTypography(_target_styles);\n const _line_height =\n _styles['lineHeight'] !== 'normal'\n ? parseInt(_styles['lineHeight'], 10) / 16 + 'rem'\n : 'normal';\n\n return (\n `\n` +\n 'font-styles: {' +\n '<ul class=\"speccer-styles\">' +\n ` <li><span class=\"property\">font-family:</span> ${_styles['fontFamily']};</li>` +\n ` <li><span class=\"property\">font-size:</span> ${_styles['fontSize']} / ${\n parseInt(_styles['fontSize'], 10) / 16\n }rem;</li>` +\n ` <li><span class=\"property\">font-weight:</span> ${_styles['fontWeight']};</li>` +\n ` <li><span class=\"property\">font-variation-settings:</span> ${_styles['fontVariationSettings']};</li>` +\n ` <li><span class=\"property\">line-height:</span> ${_styles['lineHeight']} / ${_line_height};</li>` +\n ` <li><span class=\"property\">letter-spacing:</span> ${_styles['letterSpacing']};</li>` +\n ` <li><span class=\"property\">font-style:</span> ${_styles['fontStyle']};</li>` +\n '</ul>' +\n '}'\n );\n};\n","import * as css from '../../../utils/css';\nimport * as number from '../../../utils/number';\nimport {\n get_horizontal_center_of_els,\n get_vertical_center_of_els,\n offset\n} from '../../../utils/position';\n\nimport { SpeccerAreaEnum } from '../../../types/enums/area';\n\nexport const position = async (\n area: string | null,\n targetEl: HTMLElement,\n speccerEl: HTMLElement\n) => {\n const _target_rect = targetEl.getBoundingClientRect();\n const SPECCER_PIN_SPACE = css.pinSpace(speccerEl);\n const _speccer_el_rect = speccerEl.getBoundingClientRect();\n const _el_offset = await offset(targetEl);\n const _left_layout_position_left =\n _el_offset.left - _speccer_el_rect.width - SPECCER_PIN_SPACE + 'px';\n const _left_layout_position_top =\n number.decimal(\n get_vertical_center_of_els(_el_offset.top, _speccer_el_rect, _target_rect)\n ) + 'px';\n const _right_layout_position_left =\n _el_offset.left + _target_rect.width + SPECCER_PIN_SPACE + 'px';\n const _right_layout_position_top =\n number.decimal(\n get_vertical_center_of_els(_el_offset.top, _speccer_el_rect, _target_rect)\n ) + 'px';\n const _top_layout_position_left =\n number.decimal(\n get_horizontal_center_of_els(\n _el_offset.left,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n const _top_layout_position_top =\n _el_offset.top - _speccer_el_rect.height - SPECCER_PIN_SPACE + 'px';\n const _bottom_layout_position_left =\n number.decimal(\n get_horizontal_center_of_els(\n _el_offset.left,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n const _bottom_layout_position_top =\n _el_offset.top + _target_rect.height + SPECCER_PIN_SPACE + 'px';\n\n let _position = {\n left: _left_layout_position_left,\n top: _left_layout_position_top\n };\n\n if (area && area.indexOf(SpeccerAreaEnum.Right) !== -1) {\n _position = {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n } else if (area && area.indexOf(SpeccerAreaEnum.Top) !== -1) {\n _position = {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n } else if (area && area.indexOf(SpeccerAreaEnum.Bottom) !== -1) {\n _position = {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n }\n\n return _position;\n};\n"],"names":["set","el","cls","avoid","length","trim","split","filter","cl","forEach","classList","add","cx","cls_obj","Object","keys","classname","join","SPECCER_LITERALS","getNumberValue","value","parseInt","pinSpace","getComputedStyle","getPropertyValue","waitForFrame","Promise","requestAnimationFrame","async","styles","Array","isArray","constructor","style","key","get","get_horizontal_center_of_els","modifier","startRect","targetRect","width","get_vertical_center_of_els","height","offset","targetEl","_target_rect","getBoundingClientRect","_el_offset_top","top","window","pageYOffset","_el_offset_left","left","pageXOffset","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","center","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","create","text","tag","_el","document","createElement","_text_content","createTextNode","appendChild","setAttribute","classnames.set","element","_target_styles","styles.get","display","opacity","visibility","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","css.getSpacing","_target_pruned_spacing_styles","property","_value","css.getNumberValue","_speccer_el","_class_name","indexOf","replace","css.getClassNameFromCSSProperty","body","spacingEl","styles.add","position","SpeccerAreaEnum","DissectAreaEnum","MeasureAreaEnum","getAreasFromString","areaString","isRightArea","includes","Right","isBottomArea","Bottom","isFullArea","Full","isEncloseArea","Enclose","isCurly","Curly","__classPrivateFieldGet","receiver","state","kind","f","TypeError","has","call","__classPrivateFieldSet","uniqueID","Math","random","toString","substring","coords","rect","xy","x","y","right","bottom","intrinsic_coords","pos","Error","_allowed_positions","_el_rect","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","options","direct","firstSet","direction","firstControl","lastControl","firstPoint","lastPoint","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","coordinates","direction_of_element","start","stop","crude","_angle","cy","ex","ey","normalize","SyntaxError","dy","dx","theta","atan2","PI","angle","degrees","RangeError","cardinal_direction_crude","cardinal_direction","DrawSVGLine","startElement","stopElement","_DrawSVGLine_canvas","this","_DrawSVGLine_originalPathElement","connect","draw","path","_path_el_id","_new_path","cloneNode","getAttribute","remove","parentNode","line","insertBefore","nextSibling","_direction","getPositionsForSVGPath","_d","getSVGPath","WeakMap","_DrawSVGLine_instances","WeakSet","_DrawSVGLine_init","contains","getElementById","DrawSVGCurlyBracket","_DrawSVGCurlyBracket_canvas","_DrawSVGCurlyBracket_originalPathElement","_first_path_element","_DrawSVGCurlyBracket_instances","_DrawSVGCurlyBracket_getPathElement","_second_path_element","firstPathElement","secondPathElement","path1pos1","path1pos2","path2pos1","path2pos2","getPositionsForCurlySVGPath","_first_path_d","_second_path_d","_DrawSVGCurlyBracket_init","area","dissectionEl","SPECCER_PIN_SPACE","css.pinSpace","SPECCER_MEASURE_SIZE","_positional_styles","position.getRec","Left","textContent","n","_text_node","_extra_class_names","_class_names","classnames.cx","sectionEl","_dissection_els","querySelectorAll","_index_to_use","targetIndex","resolve","_areas_string","Outline","_literal_to_use","toLowerCase","_dissection_el","_dissection_styles","SVG","Width","_measure_el","SPECCER_DEFAULT_MEASURE_SIZE","Height","isHeightArea","markElement","classNames","decimal","number","decimals","parseFloat","toFixed","html","innerHTML","activate","speccer","speccerEventFunc","func","wait","immediate","timeout","context","args","callNow","clearTimeout","setTimeout","apply","debounce","removeEventListener","addEventListener","dom","readyState","lazy","_spec_observer","IntersectionObserver","els","observer","intersectionRatio","spec.element","target","unobserve","observe","_measure_observer","measure.element","_dissect_observer","dissect.element","manual","_script","currentScript","_speccer_script_src","hasAttribute","resize.activate","spacing","__spacing","dissect","measure","mark","elementToMark","positionalStyles","markStyles","typography","_area","_html","_styles","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","css.getTypography","_line_height","template","_position","speccerEl","_speccer_el_rect","_el_offset","_left_layout_position_left","_left_layout_position_top","number.decimal","_right_layout_position_left","_right_layout_position_top","_top_layout_position_left","_top_layout_position_top","_bottom_layout_position_left","_bottom_layout_position_top","Top","modes","selector","e","node.removeAll","_els_to_be_specced","_els_to_be_measured","_els_to_be_typography_specced","_els_to_be_dissected"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"speccer.js","sources":["src/utils/node.ts","src/utils/classnames.ts","src/utils/constants.ts","src/utils/css.ts","src/utils/wait.ts","src/utils/styles.ts","src/utils/position.ts","src/features/spacing/index.ts","src/features/spacing/utils/position.ts","src/types/enums/area.ts","src/utils/area.ts","src/utils/id.ts","src/utils/coords.ts","src/utils/xy.ts","src/utils/intrinsic-coords.ts","src/utils/get-coords-pair-from-objects.ts","src/utils/bezier.ts","src/utils/direction-of-element.ts","src/utils/angle.ts","src/utils/cardinal.ts","src/utils/classes/DrawSVGLine.ts","src/utils/classes/DrawSVGCurlyBracket.ts","src/features/dissect/utils/styles.ts","src/features/dissect/index.ts","src/features/measure/index.ts","src/features/mark/index.ts","src/utils/number.ts","src/features/typography/index.ts","src/features/typography/utils/template.ts","src/features/typography/utils/position.ts","src/utils/resize.ts","src/utils/debounce.ts","src/config/browser.ts","src/main.ts"],"sourcesContent":["/**\n * Inserts an HTML element after another element in the DOM.\n *\n * @param {HTMLElement | null} el - The reference element after which the new element will be inserted.\n * @param {HTMLElement} newSibling - The new element to be inserted.\n * @returns {Element|null}\n *\n * @example\n * ```ts\n * // Insert an element after another element\n * const referenceElement = document.getElementById('reference-element');\n * const newElement = document.createElement('div');\n * after(referenceElement, newElement);\n */\nexport const after = (\n el: HTMLElement | null,\n newSibling: HTMLElement\n): Element | null => el && el.insertAdjacentElement('afterend', newSibling);\n\n/**\n * Removes all elements matching a selector from the DOM.\n *\n * @param {string} selector - The CSS selector used to select elements for removal.\n * @param {Document} el - The document context (default is the global `document` object).\n * @returns {void}\n *\n * @example\n * ```ts\n * // Remove all elements with a specific class from the document\n * removeAll('.my-class');\n * ```\n */\nexport const removeAll = (selector: string, el: Document = document): void => {\n [].forEach.call(el.querySelectorAll(selector), function (e: HTMLElement) {\n e.remove();\n });\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { ClassNamesObjectMapInterface } from 'types/interfaces/classnames';\n\n/**\n * Add CSS classes to an HTML element.\n *\n * @param {HTMLElement} el - The HTML element to which classes should be added.\n * @param {string} cls - The CSS classes to add, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid adding.\n * @returns {void}\n * @example\n * ```ts\n * // Add classes to an HTML element\n * const element = document.getElementById('example');\n * set(element, 'class1 class2');\n * ```\n */\nexport const set = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.add(cl));\n};\n\n/**\n * Toggle CSS classes on an HTML element.\n *\n * @param {HTMLElement} el - The HTML element on which classes should be toggled.\n * @param {string} cls - The CSS classes to toggle, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid toggling.\n * @returns {void}\n * @example\n * ```ts\n * // Toggle classes on an HTML element\n * const element = document.getElementById('example');\n * toggle(element, 'class1 class2');\n * ```\n */\nexport const toggle = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.toggle(cl));\n};\n\n/**\n * Remove CSS classes from an HTML element.\n *\n * @param {HTMLElement} el - The HTML element from which classes should be removed.\n * @param {string} cls - The CSS classes to remove, separated by spaces.\n * @param {string} [avoid='noop'] - Classes to avoid removing.\n * @returns {void}\n * @example\n * ```ts\n * // Remove classes from an HTML element\n * const element = document.getElementById('example');\n * remove(element, 'class1 class2');\n * ```\n */\nexport const remove = (el: HTMLElement, cls: string, avoid = 'noop') => {\n if (!el) return;\n\n if (!cls || (cls && cls.length === 0)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .forEach((cl) => el.classList.remove(cl));\n};\n\n/**\n * Generate CSS classes from a string and an object.\n *\n * @param {string} cls - Additional CSS classes as a string.\n * @param {ClassNamesObjectMapInterface} cls_obj - A mapping of class names to boolean values.\n * @returns {string} - A space-separated string of CSS class names.\n * @example\n * ```ts\n * // Generate CSS classes from a string and an object\n * const classNames = cx('class1', { class2: true, class3: false });\n * console.log(classNames); // Example output: 'class1 class2'\n * ```\n */\nexport const cx = (\n cls: string,\n cls_obj?: ClassNamesObjectMapInterface\n): string => {\n if (!cls) return '';\n\n if (!cls_obj && typeof cls !== 'string') {\n return `${Object.keys(cls)\n .filter((classname) => cls[classname])\n .join(' ')}`.trim();\n }\n\n return `${cls} ${\n cls_obj\n ? Object.keys(cls_obj)\n .filter((classname) => cls_obj[classname])\n .join(' ')\n : ''\n }`.trim();\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Array of uppercase letters.\n *\n * @type {string[]}\n * @example\n * ```ts\n * // Access the array of uppercase letters\n * const letters = SPECCER_LITERALS;\n * console.log(letters); // Example output: ['A', 'B', 'C', ...]\n * ```\n */\nexport const SPECCER_LITERALS = [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'];\n\n/**\n * Array of HTML tags to avoid when processing.\n *\n * @type {string[]}\n * @example\n * ```ts\n * // Access the array of tags to avoid\n * const tagsToAvoid = SPECCER_TAGS_TO_AVOID;\n * console.log(tagsToAvoid); // Example output: ['TR', 'TH', 'TD', ...]\n * ```\n */\nexport const SPECCER_TAGS_TO_AVOID = [\n 'TR',\n 'TH',\n 'TD',\n 'TBODY',\n 'THEAD',\n 'TFOOT'\n];\n\n/**\n * Default value for pin space.\n *\n * @type {number}\n * @example\n * ```ts\n * // Access the default pin space value\n * const defaultPinSpace = SPECCER_DEFAULT_PIN_SPACE;\n * console.log(defaultPinSpace); // Example output: 48\n * ```\n */\nexport const SPECCER_DEFAULT_PIN_SPACE = 48;\n\n/**\n * Negative default value for pin space.\n *\n * @type {number}\n * @example\n * ```ts\n * // Access the negative default pin space value\n * const negativeDefaultPinSpace = SPECCER_DEFAULT_PIN_SPACE_NEG;\n * console.log(negativeDefaultPinSpace); // Example output: -48\n * ```\n */\nexport const SPECCER_DEFAULT_PIN_SPACE_NEG = SPECCER_DEFAULT_PIN_SPACE * -1;\n\n/**\n * Default value for measure size.\n *\n * @type {number}\n * @example\n * ```ts\n * // Access the default measure size value\n * const defaultMeasureSize = SPECCER_DEFAULT_MEASURE_SIZE;\n * console.log(defaultMeasureSize); // Example output: 8\n * ```\n */\nexport const SPECCER_DEFAULT_MEASURE_SIZE = 8;\n\n/**\n * Negative default value for measure size.\n *\n * @type {number}\n * @example\n * ```ts\n * // Access the negative default measure size value\n * const negativeDefaultMeasureSize = SPECCER_DEFAULT_MEASURE_SIZE_NEG;\n * console.log(negativeDefaultMeasureSize); // Example output: -8\n * ```\n */\nexport const SPECCER_DEFAULT_MEASURE_SIZE_NEG =\n SPECCER_DEFAULT_MEASURE_SIZE * -1;\n\n/**\n * Default line width value.\n *\n * @type {number}\n * @example\n * ```ts\n * // Access the default line width value\n * const defaultLineWidth = SPECCER_DEFAULT_LINE_WIDTH;\n * console.log(defaultLineWidth); // Example output: 1\n * ```\n */\nexport const SPECCER_DEFAULT_LINE_WIDTH = 1;\n","/* eslint no-console:0 */\n'use strict';\nimport {\n SPECCER_DEFAULT_PIN_SPACE,\n SPECCER_DEFAULT_MEASURE_SIZE,\n SPECCER_DEFAULT_LINE_WIDTH\n} from './constants';\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\n\n/**\n * Parses a string value into an integer.\n *\n * @param {string} value - The string value to parse.\n * @returns {number} - The parsed integer value.\n *\n * @example\n * ```ts\n * // Parse a string value into an integer\n * const intValue = getNumberValue(\"42\");\n * console.log(intValue); // Example output: 42\n * ```\n */\nexport const getNumberValue = (value: string): number => parseInt(value, 10);\n\n/**\n * Normalizes a string or number value to ensure it's a valid number.\n * If the value is within the range [0, 1] or [-1, 0), it's normalized to 0.\n *\n * @param {string | number} value - The value to normalize.\n * @returns {number} - The normalized number value.\n *\n * @example\n * ```ts\n * // Normalize a value to ensure it's a valid number\n * const normalizedValue = normalizeNumberValue(\"0.5\");\n * console.log(normalizedValue); // Example output: 0.5\n * ```\n */\nexport const normalizeNumberValue = (value: string | number): number => {\n const _value = parseFloat(value + '');\n\n return (_value >= 0 && _value < 1) || (_value <= 0 && _value > -1)\n ? 0\n : _value;\n};\n\n/**\n * Converts a CSS property name with \"Top\", \"Right\", \"Bottom\", or \"Left\" into a class name.\n *\n * @param {string} property - The CSS property name.\n * @returns {string} - The corresponding class name.\n *\n * @example\n * ```ts\n * // Convert a CSS property name to a class name\n * const className = getClassNameFromCSSProperty(\"marginTop\");\n * console.log(className); // Example output: \"margin top\"\n * ```\n */\nexport const getClassNameFromCSSProperty = (property: string): string => {\n if (property.indexOf('Top') !== -1) {\n return property.replace('Top', ' top');\n } else if (property.indexOf('Right') !== -1) {\n return property.replace('Right', ' right');\n } else if (property.indexOf('Bottom') !== -1) {\n return property.replace('Bottom', ' bottom');\n } else if (property.indexOf('Left') !== -1) {\n return property.replace('Left', ' left');\n }\n\n return '';\n};\n\n/**\n * Extracts spacing-related CSS properties from a style object.\n *\n * @param {SpacingCSSPropertiesType} style - The style object.\n * @returns {SpacingCSSPropertiesType} - The extracted spacing-related properties.\n *\n * @example\n * ```ts\n * // Extract spacing-related properties from a style object\n * const spacing = getSpacing({\n * marginTop: \"10px\",\n * marginLeft: \"20px\",\n * });\n * console.log(spacing); // Example output: { marginTop: \"10px\", marginLeft: \"20px\" }\n * ```\n */\nexport const getSpacing = (\n style: SpacingCSSPropertiesType\n): SpacingCSSPropertiesType => {\n const {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n } = style;\n\n return {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n };\n};\n\n/**\n * Extracts typography-related CSS properties from a style object.\n *\n * @param {TypographyCSSPropertiesType} style - The style object.\n * @returns {TypographyCSSPropertiesType} - The extracted typography-related properties.\n *\n * @example\n * ```ts\n * // Extract typography-related properties from a style object\n * const typography = getTypography({\n * fontSize: \"16px\",\n * fontWeight: \"bold\",\n * });\n * console.log(typography); // Example output: { fontSize: \"16px\", fontWeight: \"bold\" }\n * ```\n */\nexport const getTypography = (\n style: TypographyCSSPropertiesType\n): TypographyCSSPropertiesType => {\n const {\n lineHeight,\n letterSpacing,\n fontFamily,\n fontSize,\n fontStyle,\n fontVariationSettings,\n fontWeight\n } = style;\n\n return {\n lineHeight,\n letterSpacing,\n fontFamily,\n fontSize,\n fontStyle,\n fontVariationSettings,\n fontWeight\n };\n};\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-pin-space\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * ```ts\n * // Get the value of a custom CSS property from an element\n * const value = pinSpace(document.body);\n * console.log(value); // Example output: 10\n * ```\n */\nexport const pinSpace = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-pin-space')\n ) || SPECCER_DEFAULT_PIN_SPACE;\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-measure-size\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * ```ts\n * // Get the value of a custom CSS property from an element\n * const value = measureSize(document.body);\n * console.log(value); // Example output: 20\n * ```\n */\nexport const measureSize = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-measure-size')\n ) || SPECCER_DEFAULT_MEASURE_SIZE;\n\n/**\n * Retrieves the value of a custom CSS property \"--ph-speccer-line-width\" from an element.\n *\n * @param {HTMLElement} el - The HTML element.\n * @returns {number} - The parsed value of the CSS property or a default value.\n *\n * @example\n * ```ts\n * // Get the value of a custom CSS property from an element\n * const value = lineWidth(document.body);\n * console.log(value); // Example output: 1.5\n * ```\n */\nexport const lineWidth = (el: HTMLElement): number =>\n getNumberValue(\n getComputedStyle(el).getPropertyValue('--ph-speccer-line-width')\n ) || SPECCER_DEFAULT_LINE_WIDTH;\n","/**\n * Waits for the specified amount of time in milliseconds.\n *\n * @param {number} ms - The number of milliseconds to wait.\n * @returns {Promise<void>} - A Promise that resolves after the specified time.\n *\n * @example\n * ```ts\n * // Wait for 1 second (1000 milliseconds)\n * await waitFor(1000);\n * ```\n */\nexport const waitFor = (ms: number): Promise<void> =>\n new Promise<void>((resolve) => setTimeout(resolve, ms));\n\n/**\n * Waits for the next animation frame using requestAnimationFrame.\n *\n * @returns {Promise<number>} - A Promise that resolves with the timestamp of the next animation frame.\n *\n * @example\n * ```ts\n * // Wait for the next animation frame and get the rect\n * await waitForFrame();\n * const rect = el.getBoundingClientRect();\n * // Wait for the next animation frame and get the timestamp\n * const timestamp = await waitForFrame();\n * ```\n */\nexport const waitForFrame = (): Promise<number> =>\n new Promise<number>(requestAnimationFrame);\n","/* eslint no-console:0 */\n'use strict';\nimport { waitForFrame } from './wait';\n\n/**\n * Adds CSS styles to an HTMLElement.\n *\n * @param {HTMLElement} el - The HTMLElement to apply styles to.\n * @param {object | Array<{ key: string; value: string }>} styles - An object or an array of objects containing CSS styles to apply.\n * @returns {Promise<void>} - A Promise that resolves after styles are applied.\n *\n * @example\n * ```ts\n * // Apply styles as an object\n * const element = document.getElementById('my-element');\n * await add(element, { color: 'red', fontSize: '16px' });\n *\n * // Apply styles as an array of objects\n * const styles = [\n * { key: 'color', value: 'blue' },\n * { key: 'backgroundColor', value: 'yellow' }\n * ];\n * await add(element, styles);\n * ```\n */\nexport const add = async (\n el: HTMLElement,\n styles: object | Array<{ key: string; value: string }>\n): Promise<void> => {\n if (\n !el ||\n !styles ||\n typeof styles === 'string' ||\n typeof styles === 'number' ||\n typeof styles === 'boolean' ||\n (Array.isArray(styles) && styles.length === 0) ||\n (Object.keys(styles).length === 0 && styles.constructor === Object)\n ) {\n return;\n }\n\n await waitForFrame();\n\n if (Array.isArray(styles)) {\n styles.forEach(\n (style: { key: string; value: string }) =>\n (el.style[style.key] = style.value)\n );\n } else {\n Object.keys(styles).forEach((key) => (el.style[key] = styles[key]));\n }\n};\n\n/**\n * Gets the computed CSS styles of an HTMLElement.\n *\n * @param {HTMLElement} el - The HTMLElement to get computed styles from.\n * @returns {Promise<CSSStyleDeclaration>} - A Promise that resolves with the computed CSS styles.\n *\n * @example\n * ```ts\n * // Get computed styles of an element\n * const element = document.getElementById('my-element');\n * const computedStyles = await get(element);\n * console.log(computedStyles.color); // Logs the color property value\n * ```\n */\nexport const get = async (el: HTMLElement): Promise<CSSStyleDeclaration> => {\n await waitForFrame();\n\n return getComputedStyle(el, null);\n};\n","import { waitForFrame } from './wait';\n\nimport { PositionPropertiesType, PositionInputType } from '../types/position';\nimport { GetRecPropertiesInterface } from 'types/interfaces/position';\n\n/**\n * Calculates the horizontal center of two elements.\n *\n * @param {number} modifier - A modifier value.\n * @param {DOMRect} startRect - The starting element's rectangle.\n * @param {DOMRect} targetRect - The target element's rectangle.\n * @returns {number} - The horizontal center position.\n *\n * @example\n * ```ts\n * // Calculate the horizontal center of two elements\n * const center = get_horizontal_center_of_els(0, startRect, targetRect);\n * ```\n */\nexport const get_horizontal_center_of_els = (\n modifier: number,\n startRect: DOMRect,\n targetRect: DOMRect\n): number => modifier - startRect.width / 2 + targetRect.width / 2;\n\n/**\n * Calculates the vertical center of two elements.\n *\n * @param {number} modifier - A modifier value.\n * @param {DOMRect} startRect - The starting element's rectangle.\n * @param {DOMRect} targetRect - The target element's rectangle.\n * @returns {number} - The vertical center position.\n *\n * @example\n * ```ts\n * // Calculate the vertical center of two elements\n * const center = get_vertical_center_of_els(0, startRect, targetRect);\n * ```\n */\nexport const get_vertical_center_of_els = (\n modifier: number,\n startRect: DOMRect,\n targetRect: DOMRect\n): number => modifier - startRect.height / 2 + targetRect.height / 2;\n\n/**\n * Gets the offset properties of an HTML element.\n *\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<PositionPropertiesType>} - A promise that resolves to the offset properties.\n *\n * @example\n * ```ts\n * // Get the offset properties of an element\n * const offsetProps = await offset(targetElement);\n * ```\n */\nexport const offset = async (\n targetEl: HTMLElement\n): Promise<PositionPropertiesType> => {\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.scrollY;\n const _el_offset_left = _target_rect.left + window.scrollX;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: _el_offset_top,\n left: _el_offset_left\n };\n};\n\n/**\n * Gets the offset properties of an HTML element with its center aligned to another element.\n *\n * @param {HTMLElement} sourceEl - The source HTML element.\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<PositionPropertiesType>} - A promise that resolves to the offset properties.\n *\n * @example\n * ```ts\n * // Get the offset properties of an element with its center aligned to another element\n * const offsetProps = await offsetWithCenter(sourceElement, targetElement);\n * ```\n */\nexport const offsetWithCenter = async (\n sourceEl: HTMLElement,\n targetEl: HTMLElement\n): Promise<PositionPropertiesType> => {\n await waitForFrame();\n\n const _source_rect = sourceEl.getBoundingClientRect();\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.scrollY;\n const _el_offset_left = _target_rect.left + window.scrollX;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: get_vertical_center_of_els(_el_offset_top, _source_rect, _target_rect),\n left: get_horizontal_center_of_els(\n _el_offset_left,\n _source_rect,\n _target_rect\n )\n };\n};\n\n/**\n * Gets various positioning properties between two HTML elements.\n *\n * @param {HTMLElement} sourceEl - The source HTML element.\n * @param {HTMLElement} targetEl - The target HTML element.\n * @returns {Promise<GetRecPropertiesInterface>} - A promise that resolves to an object with positioning functions.\n *\n * @example\n * ```ts\n * // Get positioning properties between two elements\n * const recProps = await getRec(sourceElement, targetElement);\n *\n * // Get the absolute position properties\n * const absoluteProps = recProps.absolute();\n *\n * // Get the position properties with the source element above the target element\n * const aboveProps = recProps.toTop();\n * ```\n */\nexport const getRec = async (\n sourceEl: HTMLElement,\n targetEl: HTMLElement\n): Promise<GetRecPropertiesInterface> => {\n await waitForFrame();\n\n const _source_rect = sourceEl.getBoundingClientRect();\n const _target_offset = await offset(targetEl);\n const _target_offset_center = await offsetWithCenter(sourceEl, targetEl);\n const _target_height = _target_offset.height;\n const _target_width = _target_offset.width;\n const _source_height = _source_rect.height;\n const _source_width = _source_rect.width;\n\n return {\n absolute: (): PositionPropertiesType => {\n return {\n top: _target_offset.top,\n left: _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n toTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + sourceHeight + modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n fromTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top - sourceHeight - modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n toBottom: ({\n center = false,\n sourceHeight = _source_height,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + targetHeight - (sourceHeight + modifier),\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n fromBottom: ({\n center = false,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: _target_offset.top + targetHeight + modifier,\n left: center ? _target_offset_center.left : _target_offset.left,\n height: _target_height,\n width: _target_width\n };\n },\n\n toLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + sourceWidth + modifier,\n height: _target_height,\n width: _target_width\n };\n },\n\n fromLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left - sourceWidth - modifier,\n height: _target_height,\n width: _target_width\n };\n },\n\n toRight: ({\n center = false,\n sourceWidth = _source_width,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + targetWidth - (sourceWidth + modifier),\n height: _target_height,\n width: _target_width\n };\n },\n\n fromRight: ({\n center = false,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => {\n return {\n top: center ? _target_offset_center.top : _target_offset.top,\n left: _target_offset.left + targetWidth + modifier,\n height: _target_height,\n width: _target_width\n };\n }\n };\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { set as setClassNames } from '../../utils/classnames';\nimport {\n getSpacing,\n getClassNameFromCSSProperty,\n getNumberValue\n} from '../../utils/css';\nimport { get as getStyles } from '../../utils/styles';\nimport { position } from './utils/position';\n\n/**\n * Create a spacing element with optional text content.\n *\n * @param {string | number} text - The optional text content for the spacing element.\n * @param {string} tag - The HTML tag for the element (default is 'span').\n * @returns {HTMLElement} - The created spacing element.\n *\n * @example\n * ```ts\n * const spacingElement = create(20, 'div');\n * document.body.appendChild(spacingElement);\n * ```\n */\nexport const create = (\n text: string | number = '',\n tag = 'span'\n): HTMLElement => {\n const _el = document.createElement(tag);\n const _text_content = document.createTextNode(text + '');\n\n _el.appendChild(_text_content);\n _el.setAttribute('title', text + 'px');\n setClassNames(_el, 'ph speccer spacing');\n\n return _el;\n};\n\n/**\n * Create and position spacing elements based on the target element's computed spacing styles.\n *\n * @param {HTMLElement} targetEl - The target element to create spacing elements for.\n * @returns {Promise<void>} - A promise that resolves after creating and positioning the spacing elements.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n */\nexport const element = async (targetEl: HTMLElement): Promise<void> => {\n if (!targetEl) return;\n\n const _target_styles = await getStyles(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n const _target_spacing_styles = getSpacing(_target_styles);\n const _target_pruned_spacing_styles = Object.keys(\n _target_spacing_styles\n ).filter((property) => {\n const _value = _target_spacing_styles[property];\n\n return _value !== '0px';\n });\n\n if (_target_pruned_spacing_styles.length === 0) return;\n\n _target_pruned_spacing_styles.forEach(async (property) => {\n const _value = getNumberValue(_target_spacing_styles[property]);\n const _speccer_el = create(_value);\n const _class_name = getClassNameFromCSSProperty(property);\n\n setClassNames(_speccer_el, _class_name);\n document.body.appendChild(_speccer_el);\n\n targetEl.classList.add('is-specced');\n await position(property, _value, _speccer_el, targetEl);\n });\n};\n","import { add as addStyles } from '../../../utils/styles';\nimport { offset } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Set the position and dimensions of a spacing element relative to a target element.\n *\n * @param {string} property - The CSS property to set (e.g., 'marginTop', 'marginLeft', etc.).\n * @param {number} value - The value of the CSS property.\n * @param {HTMLElement} spacingEl - The spacing element.\n * @param {HTMLElement} targetEl - The target element.\n * @returns {Promise<void>} - A promise that resolves after setting the position and dimensions.\n *\n * @example\n * ```ts\n * const spacingElement = document.getElementById('spacing');\n * const targetElement = document.getElementById('target');\n * position('marginTop', 20, spacingElement, targetElement);\n * ```\n */\nexport const position = async (\n property: string,\n value: number,\n spacingEl: HTMLElement,\n targetEl: HTMLElement\n): Promise<void> => {\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _target_offset = await offset(targetEl);\n\n if (property === 'marginTop') {\n addStyles(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top - value + 'px'\n });\n }\n\n if (property === 'marginRight') {\n addStyles(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left + parseInt(_target_rect.width + '', 10) + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'marginBottom') {\n addStyles(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top + parseInt(_target_rect.height + '', 10) + 'px'\n });\n }\n\n if (property === 'marginLeft') {\n addStyles(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left - value + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingTop') {\n addStyles(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingBottom') {\n addStyles(spacingEl, {\n height: `${value}px`,\n width: _target_rect.width + 'px',\n left: _target_offset.left + 'px',\n top:\n _target_offset.top +\n (parseInt(_target_rect.height + '', 10) - value) +\n 'px'\n });\n }\n\n if (property === 'paddingRight') {\n addStyles(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left:\n _target_offset.left +\n (parseInt(_target_rect.width + '', 10) - value) +\n 'px',\n top: _target_offset.top + 'px'\n });\n }\n\n if (property === 'paddingLeft') {\n addStyles(spacingEl, {\n height: _target_rect.height + 'px',\n width: `${value}px`,\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n });\n }\n};\n","/* eslint-disable no-unused-vars */\n\n/**\n * Enum representing different areas in Speccer.\n */\nexport enum SpeccerAreaEnum {\n Empty = '', // Represents an empty area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom',// Represents the bottom area\n Top = 'top', // Represents the top area\n}\n\n/**\n * Enum representing different areas in Dissect.\n */\nexport enum DissectAreaEnum {\n Outline = 'outline', // Represents an outline area\n Enclose = 'enclose', // Represents an enclose area\n Full = 'full', // Represents a full area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom', // Represents the bottom area\n Top = 'top', // Represents the top area\n SVG = 'svg', // Represents an SVG area\n Curly = 'curly', // Represents a curly area\n}\n\n/**\n * Enum representing different measurement areas.\n */\nexport enum MeasureAreaEnum {\n Width = 'width', // Represents the width measurement area\n Height = 'height', // Represents the height measurement area\n Left = 'left', // Represents the left measurement area\n Right = 'right', // Represents the right measurement area\n Bottom = 'bottom', // Represents the bottom measurement area\n Top = 'top', // Represents the top measurement area\n}\n","import { DissectAreaEnum, MeasureAreaEnum } from 'types/enums/area';\n\n/**\n * Splits a string containing areas into an array of strings.\n *\n * @param areaString - The string containing areas.\n * @returns An array of area strings.\n *\n * @example\n * ```ts\n * const areas = getAreasFromString('left right top');\n * // areas: ['left', 'right', 'top']\n * ```\n */\nexport const getAreasFromString = (areaString: string): string[] =>\n areaString.split(' ');\n\n/**\n * Checks if 'left' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'left' is present, otherwise `false`.\n */\nexport const isLeftArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Left);\n};\n\n/**\n * Checks if 'right' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'right' is present, otherwise `false`.\n */\nexport const isRightArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Right);\n};\n\n/**\n * Checks if 'top' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'top' is present, otherwise `false`.\n */\nexport const isTopArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Top);\n};\n\n/**\n * Checks if 'bottom' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'bottom' is present, otherwise `false`.\n */\nexport const isBottomArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Bottom);\n};\n\n/**\n * Checks if 'full' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'full' is present, otherwise `false`.\n */\nexport const isFullArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Full);\n};\n\n/**\n * Checks if 'enclose' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'enclose' is present, otherwise `false`.\n */\nexport const isEncloseArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Enclose);\n};\n\n/**\n * Checks if 'height' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'height' is present, otherwise `false`.\n */\nexport const isHeightArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Height);\n};\n\n/**\n * Checks if 'width' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'width' is present, otherwise `false`.\n */\nexport const isWidthArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Width);\n};\n\n/**\n * Checks if the provided areaString contains SVG-related areas.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if any SVG-related area is present, otherwise `false`.\n */\nexport const useSVG = (areaString: string): boolean =>\n areaString.includes(DissectAreaEnum.SVG) ||\n areaString.includes(DissectAreaEnum.Curly) ||\n areaString.includes(DissectAreaEnum.Full) ||\n areaString.includes(DissectAreaEnum.Enclose);\n\n/**\n * Checks if the provided areaString contains 'curly' and 'full' areas.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if both 'curly' and 'full' are present, otherwise `false`.\n */\nexport const isCurly = (areaString: string): boolean =>\n areaString.includes(DissectAreaEnum.Curly) &&\n areaString.includes(DissectAreaEnum.Full);\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Generates a unique ID consisting of an underscore followed by a random alphanumeric string.\n *\n * @returns {string} - A unique ID.\n *\n * @example\n * ```ts\n * // Generate a unique ID\n * const id = uniqueID();\n * console.log(id); // Example output: \"_abc123def\"\n * ```\n */\nexport const uniqueID = (): string =>\n '_' + Math.random().toString(36).substring(2, 11);\n","/**\n * A set of functions to retrieve specific coordinates from a DOMRect.\n */\nexport const coords = {\n /**\n * Get the top coordinate of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the top coordinate from.\n * @returns {number} The top coordinate.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topCoordinate = coords.top(rect);\n * ```\n */\n top: (rect: DOMRect): number => rect.top,\n\n /**\n * Get the right coordinate of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the right coordinate from.\n * @returns {number} The right coordinate.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightCoordinate = coords.right(rect);\n * ```\n */\n right: (rect: DOMRect): number => rect.left + rect.width,\n\n /**\n * Get the bottom coordinate of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the bottom coordinate from.\n * @returns {number} The bottom coordinate.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomCoordinate = coords.bottom(rect);\n * ```\n */\n bottom: (rect: DOMRect): number => rect.top + rect.height,\n\n /**\n * Get the left coordinate of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the left coordinate from.\n * @returns {number} The left coordinate.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftCoordinate = coords.left(rect);\n * ```\n */\n left: (rect: DOMRect): number => rect.left,\n\n /**\n * Get the x-coordinate of the center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the x-coordinate of the center from.\n * @returns {number} The x-coordinate of the center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const centerXCoordinate = coords.center_x(rect);\n * ```\n */\n center_x: (rect: DOMRect): number => rect.left + rect.width / 2,\n\n /**\n * Get the y-coordinate of the center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the y-coordinate of the center from.\n * @returns {number} The y-coordinate of the center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const centerYCoordinate = coords.center_y(rect);\n * ```\n */\n center_y: (rect: DOMRect): number => rect.top + rect.height / 2\n};\n","import { coords } from './coords';\n\n/**\n * Object containing functions to retrieve specific x and y coordinates from a DOMRect.\n */\nexport const xy = {\n /**\n * Get the x and y coordinates of the center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {{ x: number, y: number }} The x and y coordinates of the center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const centerCoordinates = xy.center(rect);\n * // centerCoordinates.x and centerCoordinates.y will contain the coordinates\n * ```\n */\n center: (rect: DOMRect): { x: number; y: number } => ({\n x: coords.center_x(rect),\n y: coords.center_y(rect)\n }),\n\n /**\n * Get the x and y coordinates of the top center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {{ x: number, y: number }} The x and y coordinates of the top center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topCenterCoordinates = xy.top(rect);\n * // topCenterCoordinates.x and topCenterCoordinates.y will contain the coordinates\n * ```\n */\n top: (rect: DOMRect): { x: number; y: number } => ({\n x: coords.center_x(rect),\n y: coords.top(rect)\n }),\n\n /**\n * Get the x and y coordinates of the right center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {{ x: number, y: number }} The x and y coordinates of the right center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightCenterCoordinates = xy.right(rect);\n * // rightCenterCoordinates.x and rightCenterCoordinates.y will contain the coordinates\n * ```\n */\n right: (rect: DOMRect): { x: number; y: number } => ({\n x: coords.right(rect),\n y: coords.center_y(rect)\n }),\n\n /**\n * Get the x and y coordinates of the bottom center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {{ x: number, y: number }} The x and y coordinates of the bottom center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomCenterCoordinates = xy.bottom(rect);\n * // bottomCenterCoordinates.x and bottomCenterCoordinates.y will contain the coordinates\n * ```\n */\n bottom: (rect: DOMRect): { x: number; y: number } => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n })\n\n // Additional functions with x and y coordinates can be added here...\n};\n","import { waitForFrame } from './wait';\nimport { xy } from './xy';\n\n/**\n * Get the intrinsic coordinates of an element based on a specified position.\n *\n * @param {HTMLElement} el - The HTML element.\n * @param {string} [pos='center'] - The position to use.\n * @throws {Error} No position given.\n * @throws {Error} The position given is not the required type.\n * @returns {Promise<{ x: number, y: number }>} - An object containing the coordinates.\n * @example\n * ```ts\n * // Get intrinsic coordinates for an element\n * const element = document.getElementById('example');\n * const coordinates = await intrinsic_coords(element, 'top-left');\n * ```\n */\nexport const intrinsic_coords = async (\n el: HTMLElement,\n pos = 'center'\n): Promise<{ x: number; y: number }> => {\n if (!pos) {\n throw new Error('No position given');\n }\n\n if (typeof pos !== 'string') {\n throw new Error(\n `The position given is not the required type: pos: ${typeof pos}`\n );\n }\n\n const _allowed_positions = [\n 'center',\n 'left',\n 'right',\n 'top',\n 'bottom',\n 'right-top',\n 'right-bottom',\n 'left-top',\n 'left-bottom',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n 'top-center',\n 'right-center',\n 'bottom-center',\n 'left-center'\n ];\n\n if (!_allowed_positions.includes(pos)) {\n throw new Error(\n `The position given does not match allowed positions to use! Valid positions are: ${_allowed_positions.join(\n ', '\n )}`\n );\n }\n\n await waitForFrame();\n\n const _el_rect = el.getBoundingClientRect();\n\n return xy[pos](_el_rect);\n};\n","import { intrinsic_coords } from './intrinsic-coords';\n\n/**\n * Get the x and y coordinates of two elements and return them as an object.\n *\n * @param {HTMLElement} el1 - The first HTML element.\n * @param {HTMLElement} el2 - The second HTML element.\n * @param {string} [pos1='center'] - The position to use for the first element.\n * @param {string} [pos2='center'] - The position to use for the second element.\n * @throws {Error} No element given.\n * @returns {Promise<{ x1: number, y1: number, x2: number, y2: number }>} - An object containing the coordinates.\n * @example\n * ```ts\n * // Get coordinates for two elements\n * const element1 = document.getElementById('element1');\n * const element2 = document.getElementById('element2');\n * const coordinates = await get_coords_pair_from_objects(element1, element2);\n * ```\n */\nexport const getCoordsPairFromObjects = async (\n el1: HTMLElement,\n el2: HTMLElement,\n pos1 = 'center',\n pos2 = 'center'\n): Promise<{ x1: number; y1: number; x2: number; y2: number }> => {\n if (!el1 || !el2) {\n throw new Error('No element given');\n }\n\n const { x: x1, y: y1 } = await intrinsic_coords(el1, pos1);\n const { x: x2, y: y2 } = await intrinsic_coords(el2, pos2);\n\n return {\n x1,\n y1,\n x2,\n y2\n };\n};\n","import {\n BezierPathOptionsType,\n CreateCoordinatesForCurveCoordParamType,\n CreateCoordinatesForCurveOptionsParamType,\n CurlyBezierPathOptionsType\n} from 'types/bezier';\nimport { getCoordsPairFromObjects } from './get-coords-pair-from-objects';\n\n/**\n * Calculates coordinates for a Bezier curve between two points.\n *\n * @param coords - The coordinates of the start and end points.\n * @param options - Options for controlling the curve's shape.\n * @returns Coordinates for the Bezier curve.\n *\n * @example\n * ```ts\n * const coordinates = createBezierCurveCoordinates(\n * { x1: 0, x2: 100, y1: 0, y2: 100 },\n * { direct: true, firstSet: true, direction: 'west' }\n * );\n * ```\n */\nexport const createBezierCurveCoordinates = (\n coords: CreateCoordinatesForCurveCoordParamType,\n options: CreateCoordinatesForCurveOptionsParamType\n) => {\n const { x1, x2, y1, y2 } = coords;\n const { direct = false, firstSet = false, direction } = options;\n const firstPoint = { x: x1, y: y1 }; // The first point of the curve\n const lastPoint = { x: x2, y: y2 }; // The last point of the curve\n\n let firstControl = { x: x1 + (x2 - x1) / 2, y: y1 }; // Control point for the first point\n let lastControl = { x: x1 + (x2 - x1) / 2, y: y2 }; // Control point for the last point\n\n if (direct) {\n if (firstSet) {\n if (direction === 'west') {\n firstControl = { x: x1 - 32, y: y1 - 16 / 2 };\n lastControl = { x: x2 + 32, y: y2 };\n } else if (direction === 'south') {\n firstControl = { x: x1 - 16 / 2, y: y1 + 32 };\n lastControl = { x: x2, y: y2 - 32 };\n } else if (direction === 'east') {\n firstControl = { x: x1 + 32, y: y1 - 16 / 2 };\n lastControl = { x: x2 - 32, y: y2 };\n } else {\n firstControl = { x: x1 - 16 / 2, y: y1 - 32 };\n lastControl = { x: x2, y: y2 + 32 };\n }\n } else {\n if (direction === 'west') {\n firstControl = { x: x1 - 32, y: y1 + 16 / 2 };\n lastControl = { x: x2 + 32, y: y2 };\n } else if (direction === 'south') {\n firstControl = { x: x1 + 16 / 2, y: y1 + 32 };\n lastControl = { x: x2, y: y2 - 32 };\n } else if (direction === 'east') {\n firstControl = { x: x1 + 32, y: y1 + 16 / 2 };\n lastControl = { x: x2 - 32, y: y2 };\n } else {\n firstControl = { x: x1 + 16 / 2, y: y1 - 32 };\n lastControl = { x: x2, y: y2 + 32 };\n }\n }\n }\n\n return {\n firstPoint,\n firstControl,\n lastPoint,\n lastControl\n };\n};\n\n/**\n * Generates an SVG path for a curved line between two HTML elements.\n *\n * @param startEl - The starting HTML element.\n * @param stopEl - The ending HTML element.\n * @param options - Options for controlling the curved line.\n * @returns The SVG path string for the curved line.\n *\n * @example\n * ```ts\n * const svgPath = getCurlySVGPath(startElement, stopElement, {\n * pos1: 'top',\n * pos2: 'bottom',\n * firstSet: true,\n * direction: 'south',\n * });\n * ```\n */\nexport const getCurlySVGPath = async (\n startEl: HTMLElement,\n stopEl: HTMLElement,\n options: CurlyBezierPathOptionsType\n) => {\n const { pos1, pos2, firstSet = false, direction } = options;\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(\n startEl,\n stopEl,\n pos1,\n pos2\n );\n const x1modifier = 0;\n const y1modifier = 0;\n\n let x2modifier = 0;\n let y2modifier = 0;\n\n // Create a gap between the pin and the bracket center\n if (direction == 'north') {\n y2modifier = 8;\n } else if (direction == 'west') {\n x2modifier = 8;\n } else if (direction == 'east') {\n x2modifier = -8;\n } else if (direction == 'south') {\n y2modifier = -8;\n }\n\n const coordinates = createBezierCurveCoordinates(\n {\n x1: x1 + x1modifier,\n x2: x2 + x2modifier,\n y1: y1 + y1modifier,\n y2: y2 + y2modifier\n },\n {\n direct: true,\n firstSet,\n direction\n }\n );\n const { firstPoint, firstControl, lastControl, lastPoint } = coordinates;\n\n return (\n `M ${firstPoint.x} ${firstPoint.y}` +\n `C ${firstControl.x} ${firstControl.y}, ${lastControl.x} ${lastControl.y}, ${lastPoint.x} ${lastPoint.y}`\n );\n};\n\n/**\n * Generates an SVG path for a straight line between two HTML elements.\n *\n * @param startEl - The starting HTML element.\n * @param stopEl - The ending HTML element.\n * @param options - Options for controlling the straight line.\n * @returns The SVG path string for the straight line.\n *\n * @example\n * ```ts\n * const svgPath = getSVGPath(startElement, stopElement, {\n * pos1: 'left',\n * pos2: 'right',\n * });\n * ```\n */\nexport const getSVGPath = async (\n startEl: HTMLElement,\n stopEl: HTMLElement,\n options: BezierPathOptionsType\n) => {\n const { pos1, pos2 } = options;\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(\n startEl,\n stopEl,\n pos1,\n pos2\n );\n const coordinates = createBezierCurveCoordinates(\n { x1, x2, y1, y2 },\n { direction: '' }\n );\n const { firstPoint, firstControl, lastControl, lastPoint } = coordinates;\n\n return (\n `M ${firstPoint.x} ${firstPoint.y}` +\n `C ${firstControl.x} ${firstControl.y}, ${lastControl.x} ${lastControl.y}, ${lastPoint.x} ${lastPoint.y}`\n );\n};\n\n/**\n * Returns positions for creating an SVG path based on a cardinal direction.\n *\n * @param direction - The cardinal direction ('east', 'west', 'south', 'north').\n * @returns Positions for creating an SVG path.\n *\n * @example\n * ```ts\n * const positions = getPositionsForSVGPath('east');\n * ```\n */\nexport const getPositionsForSVGPath = (direction: string) => {\n let pos1: string;\n let pos2: string;\n\n switch (direction) {\n case 'east':\n pos1 = 'right';\n pos2 = 'left';\n break;\n case 'south':\n pos1 = 'bottom';\n pos2 = 'top';\n break;\n case 'west':\n pos1 = 'left';\n pos2 = 'right';\n break;\n case 'north':\n default:\n pos1 = 'top';\n pos2 = 'bottom';\n break;\n }\n\n return { pos1, pos2 };\n};\n\n/**\n * Returns positions for creating an SVG path for a curved line based on a cardinal direction.\n *\n * @param direction - The cardinal direction ('east', 'west', 'south', 'north').\n * @returns Positions for creating an SVG path for a curved line.\n *\n * @example\n * ```ts\n * const positions = getPositionsForCurlySVGPath('west');\n * ```\n */\nexport const getPositionsForCurlySVGPath = (direction: string) => {\n let path1pos1: string;\n let path1pos2: string;\n let path2pos1: string;\n let path2pos2: string;\n\n switch (direction) {\n case 'east':\n path1pos1 = 'right-top';\n path1pos2 = 'left-center';\n path2pos1 = 'right-bottom';\n path2pos2 = 'left-center';\n break;\n case 'south':\n path1pos1 = 'bottom-left';\n path1pos2 = 'top-center';\n path2pos1 = 'bottom-right';\n path2pos2 = 'top-center';\n break;\n case 'west':\n path1pos1 = 'left-top';\n path1pos2 = 'right-center';\n path2pos1 = 'left-bottom';\n path2pos2 = 'right-center';\n break;\n case 'north':\n default:\n path1pos1 = 'top-left';\n path1pos2 = 'bottom-center';\n path2pos1 = 'top-right';\n path2pos2 = 'bottom-center';\n break;\n }\n\n return {\n path1pos1,\n path1pos2,\n path2pos1,\n path2pos2\n };\n};\n","import { angle } from './angle';\nimport { cardinal_direction, cardinal_direction_crude } from './cardinal';\nimport { getCoordsPairFromObjects } from './get-coords-pair-from-objects';\n\n/**\n * Get the direction of an element based on its position relative to another element.\n *\n * @param {Object} options - Options for direction calculation.\n * @param {HTMLElement} options.start - The starting HTML element.\n * @param {HTMLElement} options.stop - The stopping HTML element.\n * @param {boolean} [options.crude=false] - If the direction should be calculated crudely (NSEW).\n * @returns {Promise<string>} - The calculated direction.\n * @example\n * ```ts\n * // Get the direction of one element relative to another\n * const startElement = document.getElementById('startElement');\n * const stopElement = document.getElementById('stopElement');\n * const direction = await direction_of_element({ start: startElement, stop: stopElement });\n * ```\n */\nexport const direction_of_element = async ({\n start,\n stop,\n crude = false\n}: {\n start: HTMLElement;\n stop: HTMLElement;\n crude?: boolean;\n}): Promise<string> => {\n const { x1, y1, x2, y2 } = await getCoordsPairFromObjects(start, stop);\n const _angle = angle(x1, y1, x2, y2);\n const _direction = crude\n ? cardinal_direction_crude(_angle)\n : cardinal_direction(_angle);\n\n return _direction;\n};\n","/**\n * Returns the angle between two sets of coordinates.\n *\n * @param {number} cx - The x-coordinate of the first point.\n * @param {number} cy - The y-coordinate of the first point.\n * @param {number} ex - The x-coordinate of the second point.\n * @param {number} ey - The y-coordinate of the second point.\n * @param {boolean} [normalize=true] - If the angle output should be normalized to a value between 0° and 360°.\n * @throws {SyntaxError} Missing input for `angle`.\n * @throws {TypeError} Parameters for `angle` do not have the required type.\n * @returns {number} The angle between the given coordinates.\n * @example\n * ```ts\n * // Calculate the angle between two points\n * const angleValue = angle(0, 0, 3, 4);\n * ```\n */\nexport const angle = (\n cx: number,\n cy: number,\n ex: number,\n ey: number,\n normalize = true\n): number => {\n if (!cx || !cy || !ex || !ey) {\n throw new SyntaxError('Missing input for `angle`');\n }\n\n if (\n typeof cx !== 'number' ||\n typeof cy !== 'number' ||\n typeof ex !== 'number' ||\n typeof ey !== 'number'\n ) {\n throw new TypeError(\n `Parameters for \\`angle\\` do not have the required type. Requires number! Got: ${typeof cx} ${typeof cy} ${typeof ex} ${typeof ey}`\n );\n }\n\n const dy = ey - cy;\n const dx = ex - cx;\n\n let theta = Math.atan2(dy, dx); // range (-PI, PI]\n\n theta *= 180 / Math.PI; // radians to degrees, range (-180, 180]\n\n if (normalize && theta < 0) theta = 360 + theta; // range [0, 360)\n\n return theta;\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Gives you the cardinal direction based on degrees.\n * Note: The degrees start at 0, which is EAST (originally, north should be 0, but here, north is 270),\n * and we travel clockwise.\n *\n * @param {number} degrees - The angle in degrees.\n * @throws {RangeError} Parameter cannot exceed 360.\n * @throws {RangeError} Parameter cannot be lower than 0.\n * @returns {string} - The cardinal direction.\n * @example\n * ```ts\n * // Get the cardinal direction for an angle in degrees\n * const direction = cardinal_direction(45);\n * ```\n */\nexport const cardinal_direction = (degrees: number): string => {\n if (degrees > 360) throw new RangeError('Parameter cannot exceed 360');\n\n if (degrees < 0) throw new RangeError('Parameter cannot be lower than 0');\n\n if (degrees >= 0 && degrees <= 22.5) {\n return 'east';\n } else if (degrees >= 22.5 && degrees <= 67.5) {\n return 'south-east';\n } else if (degrees >= 67.5 && degrees <= 112.5) {\n return 'south';\n } else if (degrees >= 112.5 && degrees <= 157.5) {\n return 'south-west';\n } else if (degrees >= 157.5 && degrees <= 202.5) {\n return 'west';\n } else if (degrees >= 202.5 && degrees <= 247.5) {\n return 'north-west';\n } else if (degrees >= 247.5 && degrees <= 292.5) {\n return 'north';\n } else if (degrees >= 292.5 && degrees <= 337.5) {\n return 'north-east';\n } else {\n return 'east';\n }\n};\n\n/**\n * Gives you the cardinal direction based on degrees (crude version).\n * Note: The degrees start at 0, which is EAST (originally, north should be 0, but here, north is 270),\n * and we travel clockwise.\n *\n * @param {number} degrees - The angle in degrees.\n * @throws {RangeError} Parameter cannot exceed 360.\n * @throws {RangeError} Parameter cannot be lower than 0.\n * @returns {string} - The cardinal direction (NSEW).\n * @example\n * ```ts\n * // Get the cardinal direction (crude) for an angle in degrees\n * const direction = cardinal_direction_crude(45);\n * ```\n */\nexport const cardinal_direction_crude = (degrees: number): string => {\n if (degrees > 360) throw new RangeError('Parameter cannot exceed 360');\n\n if (degrees < 0) throw new RangeError('Parameter cannot be lower than 0');\n\n if (degrees >= 45 && degrees <= 135) {\n return 'south';\n } else if (degrees > 135 && degrees <= 225) {\n return 'west';\n } else if (degrees > 225 && degrees <= 315) {\n return 'north';\n } else if (degrees > 315) {\n return 'east';\n } else {\n return 'east';\n }\n};\n","'use strict';\n\nimport { uniqueID } from '../id';\nimport { getPositionsForSVGPath, getSVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\n\n/**\n * Class representing a DrawSVGLine instance.\n */\nexport class DrawSVGLine {\n #canvas: HTMLElement | SVGElement | null;\n #originalPathElement: HTMLElement | SVGPathElement | null;\n startElement: HTMLElement;\n stopElement: HTMLElement;\n line: SVGPathElement;\n\n /**\n * Creates a new DrawSVGLine instance.\n * @param startElement - The starting element for the line.\n * @param stopElement - The ending element for the line.\n */\n constructor(startElement: HTMLElement, stopElement: HTMLElement) {\n this.#init(startElement, stopElement);\n }\n\n /**\n * Initializes the DrawSVGLine instance.\n * @param startElement - The starting element for the line.\n * @param stopElement - The ending element for the line.\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(startElement: HTMLElement, stopElement: HTMLElement) {\n if (!startElement || !stopElement) {\n throw new Error('Missing inputs startElement and stopElement');\n }\n\n if (!document.body.contains(stopElement)) {\n throw new Error('stopElement is not in the DOM');\n }\n\n if (!document.body.contains(startElement)) {\n throw new Error('startElement is not in the DOM');\n }\n\n this.startElement = startElement;\n this.stopElement = stopElement;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n this.#originalPathElement = document.getElementById('ph-speccer-path');\n\n if (!this.#originalPathElement || !this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw lines. Please see the documentation'\n );\n }\n\n this.connect();\n }\n\n /**\n * Connects and draws the line.\n */\n connect() {\n this.draw(this.#originalPathElement as SVGPathElement);\n }\n\n /**\n * Draws the line based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n */\n async draw(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to draw!');\n }\n\n const _id = uniqueID();\n const _path_el_id = `ph_draw_path-path-${_id}`;\n const _new_path = path.cloneNode(false) as SVGPathElement;\n\n _new_path.setAttribute('id', _path_el_id);\n _new_path.setAttribute(\n 'data-start-el',\n this.startElement.getAttribute('id') || 'no-id-found'\n );\n _new_path.classList.remove('original');\n _new_path.classList.add('speccer');\n\n if (path.parentNode) {\n this.line = path.parentNode.insertBefore(_new_path, path.nextSibling);\n } else {\n throw new Error('No parentNode found for path');\n }\n\n const _direction = await direction_of_element({\n start: this.startElement,\n stop: this.stopElement,\n crude: true\n });\n const { pos1, pos2 } = getPositionsForSVGPath(_direction);\n const _d = await getSVGPath(this.startElement, this.stopElement, {\n pos1,\n pos2\n });\n\n this.line.setAttribute('data-direction', _direction);\n this.line.setAttribute('data-pos1', pos1);\n this.line.setAttribute('data-pos2', pos2);\n\n this.line.setAttribute('d', _d); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawSVGLine = DrawSVGLine;\n","'use strict';\n\nimport { uniqueID } from '../id';\nimport { getCurlySVGPath, getPositionsForCurlySVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\n\n/**\n * Class representing a DrawSVGCurlyBracket instance.\n */\nexport class DrawSVGCurlyBracket {\n #canvas: HTMLElement | SVGElement | null;\n #originalPathElement: HTMLElement | SVGPathElement | null;\n startElement: HTMLElement;\n stopElement: HTMLElement;\n firstPathElement: SVGPathElement;\n secondPathElement: SVGPathElement;\n\n /**\n * Creates a new DrawSVGCurlyBracket instance.\n * @param startElement - The starting element for the bracket.\n * @param stopElement - The ending element for the bracket.\n */\n constructor(startElement: HTMLElement, stopElement: HTMLElement) {\n this.#init(startElement, stopElement);\n }\n\n /**\n * Initializes the DrawSVGCurlyBracket instance.\n * @param startElement - The starting element for the bracket.\n * @param stopElement - The ending element for the bracket.\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(startElement: HTMLElement, stopElement: HTMLElement) {\n if (!startElement || !stopElement) {\n throw new Error('Missing inputs startElement and stopElement');\n }\n\n if (!document.body.contains(stopElement)) {\n throw new Error('stopElement is not in the DOM');\n }\n\n if (!document.body.contains(startElement)) {\n throw new Error('startElement is not in the DOM');\n }\n\n this.startElement = startElement;\n this.stopElement = stopElement;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n this.#originalPathElement = document.getElementById('ph-speccer-path');\n\n if (!this.#originalPathElement || !this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw lines. Please see the documentation'\n );\n }\n\n this.connect();\n }\n\n /**\n * Connects and draws the curly bracket.\n */\n connect() {\n this.draw(this.#originalPathElement as SVGPathElement);\n }\n\n /**\n * Creates a new path element based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n * @returns A new SVGPathElement.\n */\n #getPathElement(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to #getPathElement!');\n }\n\n const _id = uniqueID();\n const _path_el_id = `ph_draw_path-path-${_id}`;\n const _new_path = path.cloneNode(false) as SVGPathElement;\n\n _new_path.setAttribute(\n 'data-start-el',\n this.startElement.getAttribute('id') || 'no-id-found'\n );\n _new_path.setAttribute('id', _path_el_id);\n _new_path.classList.remove('original');\n _new_path.classList.add('speccer');\n\n return _new_path;\n }\n\n /**\n * Draws the curly bracket based on the provided path.\n * @param path - The SVGPathElement to be used as the base path.\n * @throws Will throw an error if no path is provided.\n */\n async draw(path: SVGPathElement) {\n if (!path) {\n throw new Error('No path given to draw!');\n }\n\n const _first_path_element = this.#getPathElement(path);\n const _second_path_element = this.#getPathElement(path);\n\n if (path.parentNode) {\n this.firstPathElement = path.parentNode.insertBefore(\n _first_path_element,\n path.nextSibling\n );\n this.secondPathElement = path.parentNode.insertBefore(\n _second_path_element,\n path.nextSibling\n );\n } else {\n throw new Error('No parentNode found for path');\n }\n\n const _direction = await direction_of_element({\n stop: this.stopElement,\n start: this.startElement,\n crude: true\n });\n const { path1pos1, path1pos2, path2pos1, path2pos2 } =\n getPositionsForCurlySVGPath(_direction);\n const _first_path_d = await getCurlySVGPath(\n this.startElement,\n this.stopElement,\n {\n pos1: path1pos1,\n pos2: path1pos2,\n firstSet: true,\n direction: _direction\n }\n );\n const _second_path_d = await getCurlySVGPath(\n this.startElement,\n this.stopElement,\n {\n pos1: path2pos1,\n pos2: path2pos2,\n direction: _direction\n }\n );\n\n this.firstPathElement.setAttribute('data-direction', _direction);\n this.firstPathElement.setAttribute('data-pos1', path1pos1);\n this.firstPathElement.setAttribute('data-pos2', path1pos2);\n this.firstPathElement.setAttribute('d', _first_path_d); // SVG attributes\n this.secondPathElement.setAttribute('data-direction', _direction);\n this.secondPathElement.setAttribute('data-pos1', path2pos1);\n this.secondPathElement.setAttribute('data-pos2', path2pos2);\n this.secondPathElement.setAttribute('d', _second_path_d); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawSVGCurlyBracket = DrawSVGCurlyBracket;\n","import { pinSpace, measureSize } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport {\n isBottomArea,\n isEncloseArea,\n isFullArea,\n isLeftArea,\n isRightArea\n} from '../../../utils/area';\nimport { DissectStylesOptionsType } from 'types/bezier';\n\n/**\n * Get styles for dissected elements based on the specified area and options.\n *\n * @param {string} area - The area description.\n * @param {HTMLElement} targetEl - The target element.\n * @param {HTMLElement} dissectionEl - The dissection element.\n * @param {DissectStylesOptionsType} options - Optional styles options.\n * @returns {Promise<{ left: string; top: string; height?: string; width?: string }>} - The computed styles.\n *\n * @example\n * ```ts\n * const area = 'top-left';\n * const targetElement = document.getElementById('target');\n * const dissectionElement = document.getElementById('dissection');\n * const options = { isCurly: true };\n * const styles = await styles(area, targetElement, dissectionElement, options);\n * console.log(styles);\n * ```\n */\nexport const styles = async (\n area: string,\n targetEl: HTMLElement,\n dissectionEl: HTMLElement,\n options?: DissectStylesOptionsType\n): Promise<{ left: string; top: string; height?: string; width?: string }> => {\n const { isCurly = false } = options || {};\n const SPECCER_PIN_SPACE = pinSpace(dissectionEl);\n const SPECCER_MEASURE_SIZE = measureSize(dissectionEl);\n const _positional_styles = await getRec(dissectionEl, targetEl);\n\n if (isEncloseArea(area)) {\n const { left, top, height, width } = _positional_styles.absolute();\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n }\n\n if (isLeftArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, height } = _positional_styles.fromLeft({\n sourceWidth: SPECCER_MEASURE_SIZE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n };\n } else {\n const { left, top } = _positional_styles.fromLeft({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else if (isRightArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, height } = _positional_styles.fromRight({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n };\n } else {\n const { left, top } = _positional_styles.fromRight({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else if (isBottomArea(area)) {\n if (isFullArea(area) && !isCurly) {\n const { left, top, width } = _positional_styles.fromBottom({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n };\n } else {\n const { left, top } = _positional_styles.fromBottom({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n } else {\n if (isFullArea(area) && !isCurly) {\n const { left, top, width } = _positional_styles.fromTop({\n center: false\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n };\n } else {\n const { left, top } = _positional_styles.fromTop({\n center: true,\n modifier: isCurly ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { DissectAreaEnum } from '../../types/enums/area';\n\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { SPECCER_LITERALS } from '../../utils/constants';\nimport { add } from '../../utils/styles';\nimport { isCurly, isEncloseArea, isFullArea, useSVG } from '../../utils/area';\nimport { DrawSVGLine } from '../../utils/classes/DrawSVGLine';\nimport { DrawSVGCurlyBracket } from '../../utils/classes/DrawSVGCurlyBracket';\n\nimport { styles } from './utils/styles';\n\n/**\n * Create a dissected element with optional text content, area description, and element type.\n *\n * @param {string} textContent - The text content to add to the element.\n * @param {string} area - The area description for styling.\n * @param {string} n - The element type.\n * @returns {HTMLElement} - The created dissected element.\n *\n * @example\n * ```ts\n * const dissectedElement = create('A', 'outline top', 'div');\n * document.body.appendChild(dissectedElement);\n * ```\n */\nexport const create = (\n textContent = '',\n area: string,\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _text_node = document.createTextNode(textContent);\n const _extra_class_names = {};\n\n if (area !== null && area !== '') {\n _extra_class_names[area] = true;\n }\n\n if (\n (!isFullArea(area) && !isEncloseArea(area)) ||\n (isFullArea(area) && isCurly(area))\n ) {\n _el.appendChild(_text_node);\n } else if (isFullArea(area) || isEncloseArea(area)) {\n _el.setAttribute('data-dissection-counter', textContent);\n }\n\n const _class_names = cx('ph speccer dissection', _extra_class_names);\n\n setClassNames(_el, _class_names);\n\n return _el;\n};\n\n/**\n * Create dissected elements based on the section element and its data-anatomy attributes.\n *\n * @param {HTMLElement} sectionEl - The section element containing dissected elements.\n * @returns {Promise<void>} - A promise that resolves after creating dissected elements.\n *\n * @example\n * ```ts\n * const sectionElement = document.getElementById('section');\n * element(sectionElement);\n * ```\n */\nexport const element = (sectionEl: HTMLElement): Promise<void> => {\n if (!sectionEl) return Promise.resolve();\n\n const _dissection_els = sectionEl.querySelectorAll('[data-anatomy]');\n\n if (_dissection_els) {\n let _index_to_use = 0;\n\n _dissection_els.forEach(async (targetEl: HTMLElement, targetIndex) => {\n if (!targetEl) return Promise.resolve();\n\n const _areas_string: string = targetEl.getAttribute('data-anatomy') || '';\n\n if (\n !_areas_string ||\n _areas_string === '' ||\n _areas_string.indexOf(DissectAreaEnum.Outline) === -1\n )\n return Promise.resolve();\n\n /**\n * If we're running out of literals to use,\n * make a new one with uppercase and lowercase pairs\n */\n let _literal_to_use = SPECCER_LITERALS[targetIndex];\n\n if (!_literal_to_use) {\n _literal_to_use = `${SPECCER_LITERALS[_index_to_use]}${SPECCER_LITERALS[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n const _dissection_el = create(_literal_to_use, _areas_string);\n\n document.body.appendChild(_dissection_el);\n\n const _dissection_styles = await styles(\n _areas_string,\n targetEl,\n _dissection_el,\n {\n isCurly: isCurly(_areas_string)\n }\n );\n\n await add(_dissection_el, _dissection_styles);\n\n if (useSVG(_areas_string)) {\n new DrawSVGLine(targetEl, _dissection_el);\n } else if (isCurly(_areas_string)) {\n new DrawSVGCurlyBracket(targetEl, _dissection_el);\n }\n });\n }\n\n return Promise.resolve();\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport {\n isBottomArea,\n isHeightArea,\n isRightArea,\n isWidthArea\n} from 'utils/area';\nimport { set as setClassNames } from '../../utils/classnames';\nimport { get as getStyles, add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\nimport { getRec } from '../../utils/position';\nimport { SPECCER_DEFAULT_MEASURE_SIZE_NEG } from 'utils/constants';\n\n/**\n * Create a measurement element with optional text, area, and element type.\n *\n * @param {string | number} text - The text to display on the element.\n * @param {string | null} area - The area to specify with CSS class.\n * @param {string} tag - The element type.\n * @returns {HTMLElement} - The created measurement element.\n *\n * @example\n * ```ts\n * const measurement = create(100, 'width bottom', 'div');\n * document.body.appendChild(measurement);\n * ```\n */\nexport const create = (\n text: string | number = '',\n area: string | null = '',\n tag = 'span'\n): HTMLElement => {\n const _el = document.createElement(tag);\n\n _el.setAttribute('title', text + 'px');\n _el.setAttribute('data-measure', parseInt(text + '', 10) + 'px');\n\n setClassNames(_el, `ph speccer measure ${area}`);\n\n return _el;\n};\n\n/**\n * Create a measurement element and add it to the body with styles matching a specified target element.\n *\n * @param {HTMLElement} targetEl - The target element to match styles with.\n * @returns {Promise<void>} - A promise that resolves after creating and styling the measurement element.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n */\nexport const element = async (targetEl: HTMLElement): Promise<void> => {\n if (!targetEl) return;\n\n const _areas_string: string | null = targetEl.getAttribute(\n 'data-speccer-measure'\n );\n\n if (_areas_string === '' || !_areas_string) {\n return;\n }\n\n const _target_styles = await getStyles(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n\n if (isWidthArea(_areas_string)) {\n if (isBottomArea(_areas_string)) {\n const _measure_el = create(_target_rect.width, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetEl);\n const { left, top, width } = _positional_styles.fromBottom({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n });\n } else {\n const _measure_el = create(_target_rect.width, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetEl);\n const { left, top, width } = _positional_styles.fromTop({\n center: false,\n modifier: SPECCER_DEFAULT_MEASURE_SIZE_NEG\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`\n });\n }\n } else if (isHeightArea(_areas_string)) {\n if (isRightArea(_areas_string)) {\n const _measure_el = create(_target_rect.height, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetEl);\n const { left, top, height } = _positional_styles.fromRight({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n });\n } else {\n const _measure_el = create(_target_rect.height, _areas_string);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetEl);\n const { left, top, height } = _positional_styles.fromLeft({\n center: false,\n modifier: SPECCER_DEFAULT_MEASURE_SIZE_NEG\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`\n });\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport { add as addStyles } from '../../utils/styles';\nimport { cx, set } from '../../utils/classnames';\nimport { getRec } from '../../utils/position';\n\n/**\n * Create a marker element with an optional element type.\n *\n * @param {string} n - The element type.\n * @returns {HTMLElement} - The created marker element.\n *\n * @example\n * ```typescript\n * const marker = create('div');\n * document.body.appendChild(marker);\n * ```\n */\nexport const create = (n = 'span'): HTMLElement => {\n const markElement = document.createElement(n);\n const classNames = cx('ph speccer mark');\n\n set(markElement, classNames);\n\n return markElement;\n};\n\n/**\n * Create a marker element and add it to the body with styles matching a specified element.\n *\n * @param {HTMLElement} elementToMark - The target element to match styles with.\n * @returns {Promise<void>} - A promise that resolves after creating and styling the marker element.\n *\n * @example\n * ```typescript\n * const elementToMark = document.getElementById('target');\n * element(elementToMark);\n * ```\n */\nexport const element = async (elementToMark: HTMLElement): Promise<void> => {\n if (!elementToMark) return Promise.resolve();\n\n const markElement = create();\n\n document.body.appendChild(markElement);\n\n const positionalStyles = await getRec(markElement, elementToMark);\n const { left, top, height, width } = positionalStyles.absolute();\n const markStyles = {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n\n await addStyles(markElement, markStyles);\n};\n","/* eslint no-console:0 */\n'use strict';\n\n/**\n * Converts a number to a string with a specified number of decimal places.\n *\n * @param {string | number} number - The number to convert.\n * @param {number} decimals - The number of decimal places (default is 3).\n * @returns {string} - The formatted number as a string.\n *\n * @example\n * ```ts\n * // Convert a number to a string with 2 decimal places\n * const formattedNumber = decimal(12.3456, 2); // \"12.34\"\n * ```\n */\nexport const decimal = (number: string | number, decimals = 3): string =>\n parseFloat(number + '').toFixed(decimals);\n","/* eslint no-console:0 */\n'use strict';\n\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { add as addStyles, get as getStyles } from '../../utils/styles';\nimport { position } from './utils/position';\nimport { template } from './utils/template';\n\n/**\n * Create a DOM element with provided HTML and optional CSS class names.\n *\n * @param {string} html - The HTML content to be set in the created element.\n * @param {string | null} area - The optional CSS class names to add.\n * @returns {HTMLElement} - The created DOM element.\n *\n * @example\n * ```ts\n * const htmlContent = '<p>This is some HTML content.</p>';\n * const cssClass = 'custom-class';\n * const createdElement = create(htmlContent, cssClass);\n * document.body.appendChild(createdElement);\n * ```\n */\nexport const create = (html: string, area: string | null): HTMLElement => {\n const _el = document.createElement('div');\n const _extra_class_names = {};\n\n if (area !== null && area !== '') {\n _extra_class_names[area] = true;\n }\n\n const _class_names = cx('ph speccer typography', _extra_class_names);\n\n _el.innerHTML = html;\n\n setClassNames(_el, _class_names);\n\n return _el;\n};\n\n/**\n * Create a specced typography element for a given target element.\n *\n * @param {HTMLElement} targetEl - The target element to specc typography for.\n * @returns {Promise<void>} - A promise that resolves once typography element is created and positioned.\n *\n * @example\n * ```ts\n * const targetElement = document.querySelector('.target');\n * if (targetElement) {\n * element(targetElement);\n * }\n * ```\n */\nexport const element = async (targetEl: HTMLElement): Promise<void> => {\n if (!targetEl) return;\n\n const _area: string | null = targetEl.getAttribute('data-speccer-typography');\n const _target_styles = await getStyles(targetEl);\n\n if (\n _target_styles.display === 'none' ||\n _target_styles.opacity === '0' ||\n _target_styles.visibility === 'hidden'\n ) {\n return;\n }\n\n targetEl.classList.add('is-specced');\n\n const _html = await template(targetEl);\n const _speccer_el = create(_html, _area);\n\n document.body.appendChild(_speccer_el);\n\n const _position = await position(_area, targetEl, _speccer_el);\n\n addStyles(_speccer_el, _position);\n};\n","import { getTypography } from '../../../utils/css';\nimport { get as getStyles } from '../../../utils/styles';\n\n/**\n * Generate a HTML string for typography styles of a target element.\n *\n * @param {HTMLElement} targetEl - The target element for which to generate typography styles.\n * @returns {Promise<string>} - A promise that resolves with the HTML string.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * const typographyStyles = await template(targetElement);\n * console.log(typographyStyles);\n * ```\n */\nexport const template = async (targetEl: HTMLElement): Promise<string> => {\n const _target_styles = await getStyles(targetEl);\n const _styles = getTypography(_target_styles);\n const _line_height =\n _styles['lineHeight'] !== 'normal'\n ? parseInt(_styles['lineHeight'], 10) / 16 + 'rem'\n : 'normal';\n\n return (\n `\n` +\n 'font-styles: {' +\n '<ul class=\"speccer-styles\">' +\n ` <li><span class=\"property\">font-family:</span> ${_styles['fontFamily']};</li>` +\n ` <li><span class=\"property\">font-size:</span> ${_styles['fontSize']} / ${\n parseInt(_styles['fontSize'], 10) / 16\n }rem;</li>` +\n ` <li><span class=\"property\">font-weight:</span> ${_styles['fontWeight']};</li>` +\n ` <li><span class=\"property\">font-variation-settings:</span> ${_styles['fontVariationSettings']};</li>` +\n ` <li><span class=\"property\">line-height:</span> ${_styles['lineHeight']} / ${_line_height};</li>` +\n ` <li><span class=\"property\">letter-spacing:</span> ${_styles['letterSpacing']};</li>` +\n ` <li><span class=\"property\">font-style:</span> ${_styles['fontStyle']};</li>` +\n '</ul>' +\n '}'\n );\n};\n","import { pinSpace } from '../../../utils/css';\nimport { decimal } from '../../../utils/number';\nimport {\n get_horizontal_center_of_els,\n get_vertical_center_of_els,\n offset\n} from '../../../utils/position';\n\nimport { SpeccerAreaEnum } from '../../../types/enums/area';\n\n/**\n * Calculate the position for the speccer element relative to the target element.\n *\n * @param {string | null} area - The area information for positioning.\n * @param {HTMLElement} targetEl - The target element.\n * @param {HTMLElement} speccerEl - The speccer element to position.\n * @returns {Promise<{ left: string, top: string }>} - A promise that resolves with the calculated position.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * const speccerElement = document.getElementById('speccer');\n * const area = 'top';\n * const position = await position(area, targetElement, speccerElement);\n * console.log(position); // { left: '10px', top: '20px' }\n * ```\n */\nexport const position = async (\n area: string | null,\n targetEl: HTMLElement,\n speccerEl: HTMLElement\n): Promise<{ left: string; top: string }> => {\n const _target_rect = targetEl.getBoundingClientRect();\n const SPECCER_PIN_SPACE = pinSpace(speccerEl);\n const _speccer_el_rect = speccerEl.getBoundingClientRect();\n const _el_offset = await offset(targetEl);\n const _left_layout_position_left =\n _el_offset.left - _speccer_el_rect.width - SPECCER_PIN_SPACE + 'px';\n const _left_layout_position_top =\n decimal(\n get_vertical_center_of_els(_el_offset.top, _speccer_el_rect, _target_rect)\n ) + 'px';\n const _right_layout_position_left =\n _el_offset.left + _target_rect.width + SPECCER_PIN_SPACE + 'px';\n const _right_layout_position_top =\n decimal(\n get_vertical_center_of_els(_el_offset.top, _speccer_el_rect, _target_rect)\n ) + 'px';\n const _top_layout_position_left =\n decimal(\n get_horizontal_center_of_els(\n _el_offset.left,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n const _top_layout_position_top =\n _el_offset.top - _speccer_el_rect.height - SPECCER_PIN_SPACE + 'px';\n const _bottom_layout_position_left =\n decimal(\n get_horizontal_center_of_els(\n _el_offset.left,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n const _bottom_layout_position_top =\n _el_offset.top + _target_rect.height + SPECCER_PIN_SPACE + 'px';\n\n let _position = {\n left: _left_layout_position_left,\n top: _left_layout_position_top\n };\n\n if (area && area.indexOf(SpeccerAreaEnum.Right) !== -1) {\n _position = {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n } else if (area && area.indexOf(SpeccerAreaEnum.Top) !== -1) {\n _position = {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n } else if (area && area.indexOf(SpeccerAreaEnum.Bottom) !== -1) {\n _position = {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n }\n\n return _position;\n};\n","'use strict';\n\nimport { SpeccerFunctionType } from 'types/speccer';\n\nimport debounce from './debounce';\n\n/**\n * Attaches a debounced event listener to the window's resize event that triggers the provided function.\n *\n * @param {SpeccerFunctionType} speccer - The function to trigger when the window is resized.\n *\n * @example\n * ```ts\n * // Define a function to be triggered on window resize\n * const mySpeccer = () => {\n * // Your logic here\n * console.log('Window resized');\n * };\n *\n * // Activate the debounced event listener\n * activate(mySpeccer);\n * ```\n */\nexport const activate = (speccer: SpeccerFunctionType): void => {\n /**\n * The debounced event listener function.\n * @type {Function}\n */\n const speccerEventFunc = () =>\n debounce(() => {\n speccer();\n }, 300);\n\n // Remove any existing resize event listeners to prevent duplicates\n window.removeEventListener('resize', speccerEventFunc);\n\n // Add the debounced resize event listener\n window.addEventListener('resize', speccerEventFunc);\n};\n","/* eslint @typescript-eslint/no-explicit-any: [\"error\", { \"fixToUnknown\": true }] */\n'use strict';\n\nimport { DebounceAnyFunctionType } from 'types/debounce';\n\n/**\n * Creates a debounced version of a function that delays its execution until after a specified waiting time has elapsed since the last time the debounced function was invoked.\n *\n * @param {DebounceAnyFunctionType} func - The function to debounce.\n * @param {number} wait - The number of milliseconds to wait before invoking the function after the last call.\n * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately after the first call.\n * @returns {DebounceAnyFunctionType} - The debounced function.\n *\n * @example\n * ```ts\n * // Create a debounced function\n * const debouncedFn = debounce((value) => {\n * console.log(value);\n * }, 500);\n *\n * // Call the debounced function\n * debouncedFn('Hello'); // This will not trigger immediate execution\n * debouncedFn('World'); // This will trigger immediate execution\n * ```\n */\nconst debounce = (\n func: DebounceAnyFunctionType,\n wait: number,\n immediate = false\n): DebounceAnyFunctionType => {\n let timeout: null | ReturnType<typeof setTimeout>;\n\n return function (context: unknown, ...args: unknown[]): void {\n const later = function (): void {\n timeout = null;\n\n if (!immediate) func.apply(context, args);\n };\n const callNow = immediate && !timeout;\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(later, wait);\n\n if (callNow) func.apply(context, args);\n };\n};\n\nexport default debounce;\n","/* eslint no-console:0 */\n'use strict';\n\nimport { SpeccerFunctionType } from 'types/speccer';\n\nimport { activate as resizeActivate } from '../utils/resize';\n\nimport { element as specElement } from '../features/spacing';\nimport { element as measureElement } from '../features/measure';\nimport { element as dissectElement } from '../features/dissect';\n\n/**\n * A function to initialize speccer when the DOM is ready.\n *\n * @param {SpeccerFunctionType} speccer - The speccer function to execute.\n *\n * @example\n * ```ts\n * // Usage example:\n * // dom(mySpeccer);\n * ```\n */\nexport const dom = (speccer: SpeccerFunctionType): void => {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n speccer();\n });\n } else {\n // `DOMContentLoaded` already fired\n speccer();\n }\n};\n\n/**\n * A function to initialize lazy speccer functionality.\n *\n * @example\n * ```ts\n * // Usage example:\n * // lazy();\n * ```\n */\nexport const lazy = (): void => {\n const _spec_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el: IntersectionObserverEntry) => {\n if (el.intersectionRatio > 0) {\n specElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document\n .querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n )\n .forEach((el) => {\n _spec_observer.observe(el);\n });\n\n const _measure_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el) => {\n if (el.intersectionRatio > 0) {\n measureElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document.querySelectorAll('[data-speccer-measure]').forEach((el) => {\n _measure_observer.observe(el);\n });\n\n const _dissect_observer = new IntersectionObserver((els, observer) => {\n els.forEach((el) => {\n if (el.intersectionRatio > 0) {\n dissectElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n });\n });\n\n document.querySelectorAll('[data-anatomy-section]').forEach((el) => {\n _dissect_observer.observe(el);\n });\n};\n\n/**\n * A function to manually activate speccer.\n *\n * @param {SpeccerFunctionType} speccer - The speccer function to execute.\n *\n * @example\n * ```ts\n * // Usage example:\n * // manual(mySpeccer);\n * ```\n */\nexport const manual = (speccer: SpeccerFunctionType): void => {\n window.speccer = speccer;\n};\n\n/**\n * A function to activate speccer based on script attributes.\n *\n * @param {SpeccerFunctionType} speccer - The speccer function to execute.\n *\n * @example\n * ```ts\n * // Usage example:\n * // activate(mySpeccer);\n * ```\n */\nexport const activate = (speccer: SpeccerFunctionType): void => {\n const _script = document.currentScript;\n\n if (_script) {\n const _speccer_script_src = _script.getAttribute('src');\n\n if (\n _speccer_script_src &&\n (_speccer_script_src.indexOf('speccer.js') !== -1 ||\n // for codepen\n _speccer_script_src.indexOf('JaXpOK.js') !== -1)\n ) {\n if (_script.hasAttribute('data-manual')) {\n manual(speccer);\n } else if (_script.hasAttribute('data-instant')) {\n speccer();\n } else if (_script.hasAttribute('data-dom')) {\n dom(speccer);\n } else if (_script.hasAttribute('data-lazy')) {\n lazy();\n } else {\n dom(speccer);\n }\n\n if (\n !_script.hasAttribute('data-manual') &&\n !_script.hasAttribute('data-lazy')\n ) {\n resizeActivate(speccer);\n }\n }\n }\n};\n","/* eslint no-console:0 */\n'use strict';\n\nimport './types/interfaces/global';\nimport { removeAll } from './utils/node';\nimport {\n create as spacingCreate,\n element as spacingElement\n} from './features/spacing';\nimport {\n create as dissectCreate,\n element as dissectElement\n} from './features/dissect';\nimport {\n create as measureCreate,\n element as measureElement\n} from './features/measure';\nimport { create as markCreate, element as markElement } from './features/mark';\nimport {\n create as typographyCreate,\n element as typographyElement\n} from './features/typography';\nimport { dom, lazy, manual, activate } from './config/browser';\n\nexport const spacing = {\n create: spacingCreate,\n element: spacingElement\n};\n\nexport const dissect = {\n create: dissectCreate,\n element: dissectElement\n};\n\nexport const measure = {\n create: measureCreate,\n element: measureElement\n};\n\nexport const mark = {\n create: markCreate,\n element: markElement\n};\n\nexport const typography = {\n create: typographyCreate,\n element: typographyElement\n};\n\nexport const modes = {\n dom,\n lazy,\n manual,\n activate\n};\n\nconst speccer = () => {\n removeAll('.speccer');\n\n const elsToBeSpecced = document.querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n );\n const elsToBeMeasured = document.querySelectorAll('[data-speccer-measure]');\n const elsToBeTypographySpecced = document.querySelectorAll(\n '[data-speccer-typography]'\n );\n const elsToBeDissected = document.querySelectorAll('[data-anatomy-section]');\n const elsToBeMarked = document.querySelectorAll('[data-speccer-mark]');\n\n elsToBeMarked.forEach(markElement);\n elsToBeSpecced.forEach(spacingElement);\n elsToBeMeasured.forEach(measureElement);\n elsToBeTypographySpecced.forEach(typographyElement);\n elsToBeDissected.forEach(dissectElement);\n};\n\nexport default speccer;\n\nactivate(speccer);\n"],"names":["set","el","cls","avoid","length","trim","split","filter","cl","forEach","classList","add","cx","cls_obj","Object","keys","classname","join","SPECCER_LITERALS","getNumberValue","value","parseInt","pinSpace","getComputedStyle","getPropertyValue","waitForFrame","Promise","requestAnimationFrame","async","styles","Array","isArray","constructor","style","key","get","get_horizontal_center_of_els","modifier","startRect","targetRect","width","get_vertical_center_of_els","height","offset","targetEl","_target_rect","getBoundingClientRect","_el_offset_top","top","window","scrollY","_el_offset_left","left","scrollX","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","center","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","create","text","tag","_el","document","createElement","_text_content","createTextNode","appendChild","setAttribute","setClassNames","element","_target_styles","getStyles","display","opacity","visibility","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","getSpacing","_target_pruned_spacing_styles","property","_value","_speccer_el","_class_name","indexOf","replace","getClassNameFromCSSProperty","body","spacingEl","addStyles","position","SpeccerAreaEnum","DissectAreaEnum","MeasureAreaEnum","getAreasFromString","areaString","isRightArea","includes","Right","isBottomArea","Bottom","isFullArea","Full","isEncloseArea","Enclose","isCurly","Curly","uniqueID","Math","random","toString","substring","coords","rect","xy","x","y","right","bottom","intrinsic_coords","pos","Error","_allowed_positions","_el_rect","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","options","direct","firstSet","direction","firstControl","lastControl","firstPoint","lastPoint","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","coordinates","direction_of_element","start","stop","crude","_angle","cy","ex","ey","normalize","SyntaxError","TypeError","dy","dx","theta","atan2","PI","angle","degrees","RangeError","cardinal_direction_crude","cardinal_direction","DrawSVGLine","canvas","originalPathElement","startElement","stopElement","line","this","init","contains","getElementById","connect","draw","path","_path_el_id","_new_path","cloneNode","getAttribute","remove","parentNode","insertBefore","nextSibling","_direction","getPositionsForSVGPath","_d","getSVGPath","DrawSVGCurlyBracket","firstPathElement","secondPathElement","getPathElement","_first_path_element","_second_path_element","path1pos1","path1pos2","path2pos1","path2pos2","getPositionsForCurlySVGPath","_first_path_d","_second_path_d","area","dissectionEl","SPECCER_PIN_SPACE","SPECCER_MEASURE_SIZE","_positional_styles","Left","textContent","n","_text_node","_extra_class_names","_class_names","sectionEl","resolve","_dissection_els","querySelectorAll","_index_to_use","targetIndex","_areas_string","Outline","_literal_to_use","toLowerCase","_dissection_el","_dissection_styles","SVG","Width","_measure_el","SPECCER_DEFAULT_MEASURE_SIZE","Height","isHeightArea","markElement","classNames","elementToMark","positionalStyles","markStyles","decimal","number","decimals","parseFloat","toFixed","html","innerHTML","_area","_html","_styles","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","getTypography","_line_height","template","_position","speccerEl","_speccer_el_rect","_el_offset","_left_layout_position_left","_left_layout_position_top","_right_layout_position_left","_right_layout_position_top","_top_layout_position_left","_top_layout_position_top","_bottom_layout_position_left","_bottom_layout_position_top","Top","activate","speccer","speccerEventFunc","func","wait","immediate","timeout","context","args","callNow","clearTimeout","setTimeout","apply","debounce","removeEventListener","addEventListener","dom","readyState","lazy","_spec_observer","IntersectionObserver","els","observer","intersectionRatio","specElement","target","unobserve","observe","_measure_observer","measureElement","_dissect_observer","dissectElement","manual","_script","currentScript","_speccer_script_src","hasAttribute","resizeActivate","spacing","spacingCreate","spacingElement","dissect","dissectCreate","measure","measureCreate","mark","markCreate","typography","typographyCreate","typographyElement","modes","selector","call","e","removeAll","elsToBeSpecced","elsToBeMeasured","elsToBeTypographySpecced","elsToBeDissected"],"mappings":"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"}
|