@phun-ky/speccer 9.6.1 → 9.6.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"speccer.esm.js","sources":["../src/types/enums/area.ts","../src/utils/area.ts","../src/utils/typeof/index.ts","../src/utils/classnames.ts","../src/features/dissect/utils/create.ts","../src/utils/id.ts","../src/utils/wait.ts","../src/utils/coords.ts","../src/utils/xy.ts","../src/utils/intrinsic-coords.ts","../src/utils/styles.ts","../src/utils/classes/DrawCircle.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/DrawSVGCurlyBracket.ts","../src/utils/classes/DrawSVGLine.ts","../src/utils/constants.ts","../src/utils/css.ts","../src/utils/style-property.ts","../src/utils/position.ts","../src/features/dissect/utils/styles.ts","../src/features/dissect/utils/dissect.ts","../src/utils/camel-case.ts","../src/features/dissect/utils/get-character-to-use.ts","../src/features/dissect/index.ts","../src/features/measure/index.ts","../src/features/spacing/utils/position.ts","../src/features/spacing/index.ts","../src/utils/resize.ts","../src/utils/debounce.ts","../src/config/browser.ts","../src/features/a11y/constants/index.ts","../src/features/a11y/utils/styles.ts","../src/features/a11y/index.ts","../src/features/grid/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/main.ts","../src/utils/node.ts"],"sourcesContent":["/* 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 Parent = 'parent', // Represents a parent area\n Enclose = 'enclose', // Represents an enclose area\n Subtle = 'subtle', // Represents an subtle 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 'subtle' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'subtle' is present, otherwise `false`.\n */\nexport const isSubtle = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Subtle);\n};\n\n/**\n * Checks if 'parent' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'parent' is present, otherwise `false`.\n */\nexport const isParentArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Parent);\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\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-disable import/no-unused-modules */\n/**\n * Checks if the given variable is a string.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a string, false otherwise.\n */\nexport const isString = (variable: unknown): boolean =>\n typeof variable === 'string';\n\n/**\n * Checks if the given variable is not a string.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a string, false otherwise.\n */\nexport const isNotString = (variable: unknown): boolean => !isString(variable);\n\n/**\n * Checks if the given variable is a number.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a number, false otherwise.\n */\nexport const isNumber = (variable: unknown): boolean =>\n typeof variable === 'number';\n\n/**\n * Checks if the given variable is not a number.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a number, false otherwise.\n */\nexport const isNotNumber = (variable: unknown): boolean => !isNumber(variable);\n\n/**\n * Checks if the given variable is a boolean.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a boolean, false otherwise.\n */\nexport const isBoolean = (variable: unknown): boolean =>\n typeof variable === 'boolean';\n\n/**\n * Checks if the given variable is not a boolean.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a boolean, false otherwise.\n */\nexport const isNotBoolean = (variable: unknown): boolean =>\n !isBoolean(variable);\n\n/**\n * Checks if the given variable is undefined.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is undefined, false otherwise.\n */\nexport const isUndefined = (variable: unknown): boolean =>\n typeof variable === 'undefined';\n\n/**\n * Checks if the given variable is not undefined.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not undefined, false otherwise.\n */\nexport const isNotUndefined = (variable: unknown): boolean =>\n !isUndefined(variable);\n","/* eslint no-console:0 */\nimport {\n ClassNamesFirstArgType,\n ClassNamesSecondArgType\n} from '../types/interfaces/classnames';\n\nimport { isNotString } from './typeof';\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.add(cl.trim()));\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.toggle(cl.trim()));\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.remove(cl.trim()));\n};\n\n/**\n * Combines class names and optional properties object into a single string of class names.\n *\n * The `cx` function takes two parameters: `cls` and `cls_obj`.\n * The `cls` parameter can be either a string representing class names or an object with\n * properties set to `true` or `false`. The `cls_obj` parameter is an optional object with\n * properties set to `true` or `false`, allowing for conditional inclusion of class names.\n *\n * @param {ClassNamesFirstArgType} cls - The class names as a string or an object with properties set to true or false.\n * @param {ClassNamesObjectMapInterface} cls_obj - An optional object with properties set to true or false to conditionally include class names.\n * @returns {string} - Returns a single string containing the combined 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: ClassNamesFirstArgType,\n cls_obj?: ClassNamesSecondArgType\n): string => {\n if (!cls) return '';\n\n if (!cls_obj && isNotString(cls))\n return Object.keys(cls)\n .filter((classname) => cls[classname])\n .join(' ')\n .trim();\n\n return `${(cls as string).trim()} ${\n cls_obj\n ? Object.keys(cls_obj)\n .filter((classname) => cls_obj[classname])\n .join(' ')\n : ''\n }`.trim();\n};\n","import {\n isCurly,\n isEncloseArea,\n isFullArea,\n isParentArea,\n isSubtle\n} from '../../../utils/area';\nimport { set as setClassNames, cx } from '../../../utils/classnames';\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} id - The id of the dissection element\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 id = '',\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 !== '') _extra_class_names[area] = true;\n\n if (\n isParentArea(area) &&\n !isFullArea(area) &&\n !isCurly(area) &&\n !isSubtle(area)\n )\n _extra_class_names['svg'] = true;\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 const _class_names = cx('ph-speccer speccer dissection', _extra_class_names);\n\n setClassNames(_el, _class_names);\n\n _el.setAttribute('id', id);\n\n return _el;\n};\n","/* eslint no-console:0 */\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 * 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","/**\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 { SpeccerCoordinatesInterface } from '../types/xy';\n\nimport { 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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftCoordinates = xy.left(rect);\n * // leftCoordinates.x and leftCoordinates.y will contain the coordinates\n * ```\n */\n left: (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.center_y(rect)\n }),\n 'right-top': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the right bottom of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the right bottom.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightBottomCoordinates = xy['right-bottom'](rect);\n * // rightBottomCoordinates.x and rightBottomCoordinates.y will contain the coordinates\n * ```\n */\n 'right-bottom': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left top of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left top.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftTop = xy['left-top'](rect);\n * // leftTop.x and leftTop.y will contain the coordinates\n * ```\n */\n 'left-top': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the left bottom of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left bottom.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftBottomCoordinates = xy['left-bottom'](rect);\n * // leftBottomCoordinates.x and leftBottomCoordinates.y will contain the coordinates\n * ```\n */\n 'left-bottom': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the top left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the top left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topLeftCoordinates = xy['top-left'](rect);\n * // topLeftCoordinates.x and topLeftCoordinates.y will contain the coordinates\n * ```\n */\n 'top-left': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the top right of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the top right.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topRightCoordinates = xy['top-right'](rect);\n * // topRightCoordinates.x and topRightCoordinates.y will contain the coordinates\n * ```\n */\n 'top-right': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the bottom left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the bottom left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomLeftCoordinates = xy['bottom-left'](rect);\n * // bottomLeftCoordinates.x and bottomLeftCoordinates.y will contain the coordinates\n * ```\n */\n 'bottom-left': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the bottom right of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the bottom right.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomRight = xy['bottom-right'](rect);\n * // bottomRight.x and bottomRight.y will contain the coordinates\n * ```\n */\n 'bottom-right': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the top center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topCenterCoordinates = xy['top-center'](rect);\n * // topCenterCoordinates.x and topCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'top-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.top(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the right center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightCenterCoordinates = xy['right-center'](rect);\n * // rightCenterCoordinates.x and rightCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'right-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.center_y(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the bottom center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomCenterCoordinates = xy['bottom-center'](rect);\n * // bottomCenterCoordinates.x and bottomCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'bottom-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftCenterCoordinates = xy['left-center'](rect);\n * // leftCenterCoordinates.x and leftCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'left-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.center_y(rect)\n })\n};\n","import { isNotString } from './typeof';\nimport { 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) throw Error('No position given');\n\n if (isNotString(pos))\n throw Error(\n `The position given is not the required type: pos: ${typeof pos}`\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 Error(\n `The position given does not match allowed positions to use! Valid positions are: ${_allowed_positions.join(\n ', '\n )}`\n );\n\n await waitForFrame();\n\n const _el_rect = el.getBoundingClientRect();\n\n return xy[pos](_el_rect);\n};\n","/* eslint no-console:0 */\nimport { isBoolean, isNumber, isString } from './typeof';\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 | { 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 | { key: string; value: string }[]\n): Promise<void> => {\n if (\n !el ||\n !styles ||\n isString(styles) ||\n isNumber(styles) ||\n isBoolean(styles) ||\n (Array.isArray(styles) && !styles.length) ||\n (!Object.keys(styles).length && styles.constructor === Object)\n )\n return;\n\n await waitForFrame();\n\n if (Array.isArray(styles))\n for (const style of styles) {\n el.style[style.key] = style.value;\n }\n else\n for (const key of Object.keys(styles)) {\n 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 { isBottomArea, isLeftArea, isRightArea } from '../area';\nimport { uniqueID } from '../id';\nimport { intrinsic_coords } from '../intrinsic-coords';\nimport { add as addStyle } from '../styles';\n\n/**\n * Class representing a DrawCircle instance.\n */\nexport class DrawCircle {\n #canvas: HTMLElement | SVGElement | null;\n el: HTMLElement;\n circle: SVGCircleElement;\n radius: number;\n areas: string;\n\n /**\n * Creates a new DrawCircle instance.\n * @param el - The element used to position the circle.\n * @param radius - The radius of the circle\n * @param areas - The areas used to identify position\n */\n constructor(el: HTMLElement, radius: number, areas: string) {\n this.#init(el, radius, areas);\n }\n\n /**\n * Initializes the DrawCircle instance.\n * @param el - The element used to position the circle.\n * @param radius - The radius of the circle\n * * @param areas - The areas used to identify position\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(el: HTMLElement, radius: number, areas: string) {\n if (!el || !radius || !areas) {\n throw new Error('Missing inputs el or radius or areas');\n }\n\n if (!document.body.contains(el)) {\n throw new Error('el is not in the DOM');\n }\n\n this.el = el;\n this.radius = radius;\n this.areas = areas;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n\n if (!this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw circles. Please see the documentation'\n );\n }\n\n const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\n });\n\n this.draw();\n }\n\n /**\n * Draws the circle based on the provided el and radius.\n */\n async draw() {\n const _id = uniqueID();\n const _circle_el_id = `ph_draw-circle-${_id}`;\n\n this.circle = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'circle'\n ) as unknown as SVGCircleElement;\n\n const _el_ID = this.el.getAttribute('id') || uniqueID();\n\n this.el.setAttribute('id', _el_ID);\n\n this.circle.setAttribute('id', _circle_el_id);\n this.circle.setAttribute('data-el', _el_ID);\n this.circle.classList.add('ph-speccer');\n this.circle.classList.add('speccer');\n this.circle.classList.add('circle');\n\n if (this.#canvas) {\n this.#canvas.appendChild(this.circle);\n } else {\n throw new Error('No parentNode found for circle');\n }\n\n let pos = 'top';\n\n if (isLeftArea(this.areas)) pos = 'left';\n\n if (isRightArea(this.areas)) pos = 'right';\n\n if (isBottomArea(this.areas)) pos = 'bottom';\n\n const { x, y } = await intrinsic_coords(this.el, pos);\n\n this.circle.setAttribute('r', this.radius + ''); // SVG attributes\n this.circle.setAttribute('cx', Math.round(x) + ''); // SVG attributes\n this.circle.setAttribute('cy', Math.round(y) + ''); // SVG attributes\n this.circle.setAttribute('fill', 'currentColor'); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawCircle = DrawCircle;\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) throw Error('No element given');\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';\n\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') y2modifier = 8;\n else if (direction === 'west') x2modifier = 8;\n else if (direction === 'east') x2modifier = -8;\n else if (direction === 'south') y2modifier = -8;\n\n const { firstPoint, firstControl, lastControl, lastPoint } =\n createBezierCurveCoordinates(\n {\n x1: x1 + x1modifier,\n x2: x2 + x2modifier,\n y1: y1 + y1modifier + document.documentElement.scrollTop,\n y2: y2 + y2modifier + document.documentElement.scrollTop\n },\n {\n direct: true,\n firstSet,\n direction\n }\n );\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 { firstPoint, firstControl, lastControl, lastPoint } =\n createBezierCurveCoordinates({ x1, x2, y1, y2 }, { direction: '' });\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","import { isNotNumber, isUndefined } from './typeof';\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 (isUndefined(cx) || isUndefined(cy) || isUndefined(ex) || isUndefined(ey))\n throw new SyntaxError('Missing input for `angle`');\n\n if (isNotNumber(cx) || isNotNumber(cy) || isNotNumber(ex) || isNotNumber(ey))\n throw 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 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; // range [0, 360)\n\n return theta;\n};\n","/* eslint no-console:0 */\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) return 'east';\n\n if (degrees >= 22.5 && degrees <= 67.5) return 'south-east';\n\n if (degrees >= 67.5 && degrees <= 112.5) return 'south';\n\n if (degrees >= 112.5 && degrees <= 157.5) return 'south-west';\n\n if (degrees >= 157.5 && degrees <= 202.5) return 'west';\n\n if (degrees >= 202.5 && degrees <= 247.5) return 'north-west';\n\n if (degrees >= 247.5 && degrees <= 292.5) return 'north';\n\n if (degrees >= 292.5 && degrees <= 337.5) return 'north-east';\n\n return 'east';\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) return 'south';\n\n if (degrees > 135 && degrees <= 225) return 'west';\n\n if (degrees > 225 && degrees <= 315) return 'north';\n\n return 'east';\n};\n","import { getCurlySVGPath, getPositionsForCurlySVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\nimport { uniqueID } from '../id';\nimport { add as addStyle } from '../styles';\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 const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\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 const dataStartElID = this.startElement.getAttribute('id') || uniqueID();\n\n this.startElement.setAttribute('id', dataStartElID);\n _new_path.setAttribute('data-start-el', dataStartElID);\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 { getPositionsForSVGPath, getSVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\nimport { uniqueID } from '../id';\nimport { add as addStyle } from '../styles';\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 const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\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 const dataStartElID = this.startElement.getAttribute('id') || uniqueID();\n\n this.startElement.setAttribute('id', dataStartElID);\n\n _new_path.setAttribute('id', _path_el_id);\n _new_path.setAttribute('data-start-el', dataStartElID);\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","/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\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: string[] = [...'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: string[] = [\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: number =\n 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: number =\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 */\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\n\nimport {\n SPECCER_DEFAULT_PIN_SPACE,\n SPECCER_DEFAULT_MEASURE_SIZE,\n SPECCER_DEFAULT_LINE_WIDTH\n} from './constants';\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.includes('Top')) return property.replace('Top', ' top');\n\n if (property.includes('Right')) return property.replace('Right', ' right');\n\n if (property.includes('Bottom')) return property.replace('Bottom', ' bottom');\n\n if (property.includes('Left')) return property.replace('Left', ' left');\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","import { waitForFrame } from './wait';\n\n/**\n * Checks if a specific CSS property of an element has a certain value.\n *\n * @param {HTMLElement} element - The target element.\n * @param {string} property - The CSS property to check.\n * @param {string} value - The expected value of the CSS property.\n * @returns {Promise<boolean>} - A promise that resolves to true if the property has the expected value, false otherwise.\n *\n * @example\n * ```ts\n * // Usage example:\n * const result = await hasStylePropertySet(myElement, 'display', 'block');\n * console.log(result); // true or false\n * ```\n */\nconst hasStylePropertySet = async (\n element: HTMLElement,\n property: string,\n value: string\n): Promise<boolean> => {\n await waitForFrame();\n\n const _computed_style = getComputedStyle(element);\n\n return _computed_style[property] === value;\n};\n/**\n * Finds the nearest parent element with a specific CSS property set to a certain value.\n *\n * @param {HTMLElement} element - The target element.\n * @param {string} property - The CSS property to check.\n * @param {string} value - The expected value of the CSS property.\n * @returns {Promise<HTMLElement | null>} - A promise that resolves to the parent element if found, or null if none.\n *\n * @example\n * ```ts\n * // Usage example:\n * const parentSticky = await getParentWithStylePropertySet(myElement, 'position', 'sticky');\n * console.log(parentSticky); // HTMLElement or null\n * ```\n */\nconst getParentWithStylePropertySet = async (\n element: HTMLElement,\n property: string,\n value: string\n): Promise<HTMLElement | null> => {\n if (!element.parentElement) return null;\n\n const hasStyleProperty = await hasStylePropertySet(\n element.parentElement,\n property,\n value\n );\n\n if (hasStyleProperty) return element.parentElement;\n\n return await getParentWithStylePropertySet(\n element.parentElement,\n property,\n value\n );\n};\n\n/**\n * Finds the nearest parent element with 'position: sticky'.\n *\n * @param {HTMLElement} element - The target element.\n * @returns {Promise<HTMLElement | null>} - A promise that resolves to the sticky parent element if found, or null if none.\n * @private\n * @example\n * ```ts\n * // Usage example:\n * const stickyParent = await getParentThatIsSticky(myElement);\n * console.log(stickyParent); // HTMLElement or null\n * ```\n */\nexport const getParentThatIsSticky = async (\n element: HTMLElement\n): Promise<HTMLElement | null> => {\n return await getParentWithStylePropertySet(element, 'position', 'sticky');\n};\n\n/**\n * Checks if an element has 'position: sticky'.\n *\n * @param {HTMLElement} element - The target element.\n * @returns {Promise<boolean>} - A promise that resolves to true if the element has 'position: sticky', false otherwise.\n *\n * @example\n * ```ts\n * // Usage example:\n * const isElementSticky = await isSticky(myElement);\n * console.log(isElementSticky); // true or false\n * ```\n */\nexport const isSticky = async (element: HTMLElement): Promise<boolean> =>\n await hasStylePropertySet(element, 'position', 'sticky');\n","import { GetRecPropertiesInterface } from '../types/interfaces/position';\nimport { PositionPropertiesType, PositionInputType } from '../types/position';\n\nimport { getParentThatIsSticky, isSticky } from './style-property';\nimport { waitForFrame } from './wait';\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 let _target_rect = targetEl.getBoundingClientRect();\n let _el_offset_top = _target_rect.top + window.scrollY;\n\n const _el_offset_left = _target_rect.left + window.scrollX;\n const stickyParentElement = await getParentThatIsSticky(targetEl);\n const isTargetSticky = await isSticky(targetEl);\n\n // if node is sticky, we need to account for that\n if (isTargetSticky) {\n const originalPosition = targetEl.style.position;\n\n await waitForFrame();\n targetEl.style.position = 'relative';\n\n await waitForFrame();\n _target_rect = targetEl.getBoundingClientRect();\n _el_offset_top = _target_rect.top;\n targetEl.style.position = originalPosition;\n }\n // If any of the parents are sticky, we need to account for that\n else if (stickyParentElement) {\n const originalPosition = stickyParentElement.style.position;\n\n await waitForFrame();\n stickyParentElement.style.position = 'relative';\n\n await waitForFrame();\n _target_rect = targetEl.getBoundingClientRect();\n _el_offset_top = _target_rect.top;\n stickyParentElement.style.position = originalPosition;\n }\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 top: _target_offset.top,\n left: _target_offset.left,\n height: _target_height,\n width: _target_width\n }),\n toTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toBottom: ({\n center = false,\n sourceHeight = _source_height,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromBottom: ({\n center = false,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toRight: ({\n center = false,\n sourceWidth = _source_width,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromRight: ({\n center = false,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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","import { DissectStylesOptionsType } from '../../../types/bezier';\nimport { SpeccerStylesReturnType } from '../../../types/styles';\nimport {\n isBottomArea,\n isEncloseArea,\n isFullArea,\n isLeftArea,\n isParentArea,\n isRightArea,\n isSubtle\n} from '../../../utils/area';\nimport { pinSpace, measureSize } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\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 {HTMLElement} parentElement - The parent element.\n * @param {DissectStylesOptionsType} options - Optional styles options.\n * @returns {Promise<SpeccerStylesReturnType>} - The computed styles.\n *\n * @example\n * ```ts\n * const area = 'top-left';\n * const targetElement = document.getElementById('target');\n * const parentElement = document.getElementById('parent');\n * const dissectionElement = document.getElementById('dissection');\n * const options = { isCurly: true };\n * const styles = await styles(area, targetElement, dissectionElement, parentElement, options);\n * console.log(styles);\n * ```\n */\nexport const styles = async (\n area: string,\n targetEl: HTMLElement,\n dissectionEl: HTMLElement,\n parentElement: HTMLElement,\n options?: DissectStylesOptionsType\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\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 (isParentArea(area) && !isFullArea(area) && !isCurly && !isSubtle(area)) {\n if (isRightArea(area)) {\n const { top } = _positional_styles.fromRight({\n center: true\n });\n\n await waitForFrame();\n\n const { left, width } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left + width + SPECCER_PIN_SPACE}px`,\n top: `${top}px`\n };\n }\n\n if (isBottomArea(area)) {\n const { left } = _positional_styles.toBottom({\n center: true\n });\n\n await waitForFrame();\n\n const { top, height } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left}px`,\n top: `${top + height + SPECCER_PIN_SPACE}px`\n };\n }\n\n if (isLeftArea(area)) {\n const { top } = _positional_styles.fromLeft({\n center: true\n });\n\n await waitForFrame();\n\n const { left } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left - SPECCER_PIN_SPACE * 1.5}px`,\n top: `${top}px`\n };\n }\n\n const { left } = _positional_styles.fromTop({\n center: true\n });\n\n await waitForFrame();\n\n const { top } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left}px`,\n top: `${top - SPECCER_PIN_SPACE * 1.5}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 }\n\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\n 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 }\n\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\n 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 }\n\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\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 }\n\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","import { DissectAreaEnum } from '../../../types/enums/area';\nimport {\n isCurly,\n isEncloseArea,\n isFullArea,\n isParentArea,\n isSubtle,\n useSVG\n} from '../../../utils/area';\nimport { camelCase } from '../../../utils/camel-case';\nimport { DrawCircle } from '../../../utils/classes/DrawCircle';\nimport { DrawSVGCurlyBracket } from '../../../utils/classes/DrawSVGCurlyBracket';\nimport { DrawSVGLine } from '../../../utils/classes/DrawSVGLine';\nimport { uniqueID } from '../../../utils/id';\nimport { add } from '../../../utils/styles';\n\nimport { create } from './create';\nimport { styles } from './styles';\n\n/**\n * Create and style the dissection element as needed.\n *\n * This function appends a new dissection element to the document body based on the anatomy data attribute\n * of the target element. It handles different styles, such as curly brackets or lines, based on the anatomy type.\n *\n * @param {HTMLElement} el - The target element that contains the anatomy data.\n * @param {string} symbol - The symbol to use.\n * @param {HTMLElement} parentElement - The parent element\n * @param {string} [areas] - Optional areas to use if not [data-anatomy] is set as an attribute on the element\n * @returns {Promise<string|void>} A promise that resolves to the id of the dissection element when the dissection is completed, or `void` if required input is invalid.\n *\n * @example\n * ```ts\n * const element = document.getElementById('target');\n * const symbol = 0;\n * dissect(element, symbol).then(() => {\n * console.log('Dissection completed');\n * });\n * ```\n */\nexport const dissect = async (\n el: HTMLElement,\n symbol: string,\n parentElement: HTMLElement,\n areas = ''\n): Promise<string | void> => {\n if (!el) return;\n\n const _areas_string: string = el.getAttribute('data-anatomy') || areas;\n\n if (\n !_areas_string ||\n _areas_string === '' ||\n !_areas_string.includes(DissectAreaEnum.Outline)\n )\n return;\n\n const _dissection_el_id = `speccer-${camelCase(_areas_string)}-${el.getAttribute('id') || uniqueID()}`;\n const _dissection_el = create(symbol, _areas_string, _dissection_el_id);\n\n el.setAttribute('data-speccer-element-id', _dissection_el_id);\n\n document.body.appendChild(_dissection_el);\n\n const _dissection_styles = await styles(\n _areas_string,\n el as HTMLElement,\n _dissection_el,\n parentElement,\n {\n isCurly: isCurly(_areas_string)\n }\n );\n\n await add(_dissection_el, _dissection_styles);\n\n const isParent =\n isParentArea(_areas_string) &&\n !isEncloseArea(_areas_string) &&\n !isFullArea(_areas_string) &&\n !isSubtle(_areas_string);\n const isSVGLine =\n isParent || (useSVG(_areas_string) && !isCurly(_areas_string));\n\n if (isSVGLine) {\n new DrawSVGLine(el as HTMLElement, _dissection_el);\n\n if (isParent) {\n new DrawCircle(el, 5, _areas_string);\n }\n } else if (isCurly(_areas_string)) {\n new DrawSVGCurlyBracket(el as HTMLElement, _dissection_el);\n }\n\n return _dissection_el_id;\n};\n","/**\n * Converts a string to camel case.\n * @param {string} str - The input string.\n * @returns {string} - The string converted to camel case.\n */\nexport const camelCase = (str: string): string =>\n str\n .normalize('NFKD') // split accented characters into their base characters and diacritical marks\n .replace(/[\\u0300-\\u036f]/g, '') // remove all the accents, which happen to be all in the \\u03xx UNICODE block.\n .trim() // trim leading or trailing whitespace\n .toLowerCase() // convert to lowercase\n .replace(/[^a-z0-9 -]/g, '') // remove non-alphanumeric characters\n .replace(/\\s+/g, ' ')\n .replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (ltr, idx) =>\n idx === 0 ? ltr.toLowerCase() : ltr.toUpperCase()\n )\n .replace(/\\s+/g, '');\n","import { SPECCER_LITERALS } from '../../../utils/constants';\n\nlet _index_to_use = 0;\n\n/**\n * Returns the character to use at the specified target index.\n * If the index exceeds the available characters, it generates a new character by pairing uppercase and lowercase letters.\n *\n * @param {number} targetIndex - The index of the character to retrieve.\n * @returns {string} The character to use at the specified index.\n *\n * @example\n * ```ts\n * const character = getCharacterToUse(0); // Returns first character from SPECCER_LITERALS\n * const nextCharacter = getCharacterToUse(25); // Returns next character or a generated pair if index exceeds literals length\n * ```\n */\nexport const getCharacterToUse = (targetIndex: number): string => {\n const _literals_to_use = window.SPECCER_LITERALS || SPECCER_LITERALS;\n\n let _character_to_use = _literals_to_use[targetIndex];\n\n // Reset index to use when we start new elements\n if (targetIndex === 0) {\n _index_to_use = 0;\n }\n\n /**\n * If we're running out of characters to use,\n * make a new one with uppercase and lowercase pairs\n */\n if (!_character_to_use) {\n _character_to_use = `${_literals_to_use[_index_to_use]}${_literals_to_use[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n return _character_to_use;\n};\n","/**\n * This feature highlights the anatomy of an element.\n *\n * ![dissect](https://github.com/phun-ky/speccer/blob/main/public/anatomy.png?raw=true)\n *\n * In your component examples, use the following attribute. Remember to use the `data-anatomy-section` as an attribute on a parent element to scope the marking.\n *\n * @example\n * ```html\n * <div data-anatomy-section>\n * <div\n * data-anatomy=\"outline [full|enclose][curly] [left|right|top|bottom]\"\n * class=\"...\"\n * ></div>\n * </div>\n * ```\n *\n * @packageDocumentation\n */\n// eslint-disable-next-line import/no-unused-modules\nexport { create } from './utils/create';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { dissect } from './utils/dissect';\n\nimport { dissect as dissectionIterator } from './utils/dissect';\nimport { getCharacterToUse } from './utils/get-character-to-use';\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 = async (sectionEl: HTMLElement): Promise<void> => {\n if (!sectionEl) return;\n\n const _dissection_els = sectionEl.querySelectorAll('[data-anatomy]');\n\n if (!_dissection_els || _dissection_els.length === 0) return;\n\n _dissection_els.forEach(\n async (targetEl: HTMLElement, targetIndex: number): Promise<void> => {\n const _character_to_use = getCharacterToUse(targetIndex);\n\n await dissectionIterator(targetEl, _character_to_use, sectionEl);\n }\n );\n};\n","/* eslint no-console:0 */\nimport {\n isBottomArea,\n isHeightArea,\n isRightArea,\n isWidthArea\n} from '../../utils/area';\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DEFAULT_MEASURE_SIZE_NEG } from '../../utils/constants';\nimport { getRec } from '../../utils/position';\nimport { get as getStyles, add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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 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 * ![measure](https://github.com/phun-ky/speccer/blob/main/public/measure.png?raw=true)\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) 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 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","import { offset } from '../../../utils/position';\nimport { add as addStyles } from '../../../utils/styles';\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 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 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 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 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 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 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 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","/* eslint no-console:0 */\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';\n\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 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 * ![spacing](https://github.com/phun-ky/speccer/blob/main/public/spacing.png?raw=true)\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 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) return;\n\n for (const property of _target_pruned_spacing_styles) {\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 { 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 }] */\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) clearTimeout(timeout);\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/**\n * Contains the helper functions to activate SPECCER via a script tag, based on attributes:\n *\n * > [!NOTE]\n * > If the activation method is dom or instant, a resize feature is activated, making sure everything is re-rendered on resize. for manual or lazy loading, you are responsible to handle resize yourself.\n *\n * > [!NOTE]\n * > Remember to add the CSS file!:\n *\n * > ```html\n * > <link rel=\"stylesheet\" href=\"../path/to/speccer.min.css\" />\n * > ```\n *\n * ## Default implementation\n * ```html\n * <script src=\"../speccer.js\"</script>\n * ```\n *\n * If no attribute is applied, it will default to `data-dom`, as in, it will initialize when `DOMContentLoaded` is fired.\n *\n * ## Manual initiation\n * ```html\n * <script src=\"../speccer.js\" data-manual</script>\n * ```\n *\n * Makes `window.speccer()` available to be used when you feel like it\n *\n * ## Initiate immediately\n * ```html\n * <script src=\"../speccer.js\" data-instant></script>\n * ```\n *\n * fires off `speccer()` right away\n *\n * ## Initiate when dom ready\n * ```html\n * <script src=\"../speccer.js\" data-dom></script>\n * ```\n *\n * Waits for `DOMContentLoaded`\n *\n * ## Initiate with lazy loading\n * ```html\n * <script src=\"../speccer.js\" data-lazy></script>\n * ```\n *\n * Lazy loads `speccer()` per specced element\n *\n * @packageDocumentation\n */\nimport { element as dissectElement } from '../features/dissect';\nimport { element as measureElement } from '../features/measure';\nimport { element as specElement } from '../features/spacing';\nimport { SpeccerFunctionType } from '../types/speccer';\nimport { activate as resizeActivate } from '../utils/resize';\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 // `DOMContentLoaded` already fired\n else speccer();\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 for (const el of els) {\n if (el.intersectionRatio > 0) {\n specElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n )) {\n _spec_observer.observe(el);\n }\n\n const _measure_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n measureElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll('[data-speccer-measure]')) {\n _measure_observer.observe(el);\n }\n\n const _dissect_observer = new IntersectionObserver(async (els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n await dissectElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll('[data-anatomy-section]')) {\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 (_speccer_script_src?.includes('speccer.js')) {\n if (_script.hasAttribute('data-manual')) manual(speccer);\n else if (_script.hasAttribute('data-instant')) speccer();\n else if (_script.hasAttribute('data-dom')) dom(speccer);\n else if (_script.hasAttribute('data-lazy')) lazy();\n else dom(speccer);\n\n if (\n !_script.hasAttribute('data-manual') &&\n !_script.hasAttribute('data-lazy')\n )\n resizeActivate(speccer);\n }\n }\n};\n","/**\n * Array of keys considered as modifiers in shortcuts.\n * @type {string[]}\n */\nexport const SPECCER_MODIFIER_KEYS: string[] = [\n 'alt',\n 'altgraph',\n 'capslock',\n 'control',\n 'fn',\n 'fnlock',\n 'hyper',\n 'meta',\n 'numlock',\n 'os',\n 'scrolllock',\n 'shift',\n 'super',\n 'symbol',\n 'command',\n 'ctrl',\n 'altgr',\n 'symbollock'\n];\n\nexport const SPECCER_PHYSICAL_KEYS: string[] = [\n 'escape',\n 'esc',\n 'enter',\n 'return',\n '⏎',\n '␛'\n];\n\n/**\n * Selector string for tabbable elements.\n * @type {string}\n */\nexport const SPECCER_TABBABLE_ELEMENTS_SELECTOR = `\n a[href], area[href], input:not([disabled]):not([tabindex='-1']),\n button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']),\n textarea:not([disabled]):not([tabindex='-1']),\n iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]\n`;\n\n/**\n * Selector string for landmark elements.\n * @type {string}\n */\nexport const SPECCER_LANDMARK_ELEMENTS_SELECTOR = `\nheader, footer, section, main, nav, aside, [role=\"section\"], [role=\"banner\"],\n[role=\"complementary\"], [role=\"contentinfo\"], [role=\"form\"], [role=\"main\"],\n[role=\"navigation\"], [role=\"region\"], [role=\"search\"]\n`;\n","import { SpeccerStylesReturnType } from '../../../types/styles';\nimport { pinSpace } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Calculates and returns the styles for an accessibility element based on its type.\n *\n * @param {string} type - Type of the accessibility element ('tabstops', 'landmark', 'region', 'shortcut', or default).\n * @param {HTMLElement} targetEl - Target HTML element.\n * @param {HTMLElement} a11yEl - Accessibility HTML element to be styled.\n * @returns {Promise<SpeccerStylesReturnType>} A Promise resolving with the calculated styles.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('targetElement');\n * const a11yElement = document.createElement('div');\n *\n * // Example for tab order element styles\n * const tabstopsStyles = await styles('tabstops', targetElement, a11yElement);\n *\n * // Example for landmark element styles\n * const landmarkStyles = await styles('landmark', targetElement, a11yElement);\n *\n * // Example for region element styles\n * const regionStyles = await styles('region', targetElement, a11yElement);\n *\n * // Example for shortcut element styles\n * const shortcutStyles = await styles('shortcut', targetElement, a11yElement);\n *\n * // Example for default styles\n * const defaultStyles = await styles('default', targetElement, a11yElement);\n * ```\n */\nexport const styles = async (\n type: string,\n targetEl: HTMLElement,\n a11yEl: HTMLElement\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const SPECCER_PIN_SPACE = pinSpace(a11yEl);\n const _positional_styles = await getRec(a11yEl, targetEl);\n\n if (type === 'tabstops') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 32;\n\n if (left <= 0) left = 32;\n\n if (top <= 0) top = 32;\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'landmark') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 16;\n top -= 16;\n\n if (left <= 0) left = 32;\n\n if (top <= 0) top = 32;\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'region') {\n const { left, top, height, width } = _positional_styles.fromTop();\n\n return {\n height: `${height}px`,\n width: `${width}px`,\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'shortcut') {\n const { left, top } = _positional_styles.fromBottom();\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n const { left, top } = _positional_styles.fromTop({\n center: true,\n modifier: SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left - 32}px`,\n top: `${top - 32}px`\n };\n};\n","/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { add } from '../../utils/styles';\n\nimport {\n SPECCER_LANDMARK_ELEMENTS_SELECTOR,\n SPECCER_MODIFIER_KEYS,\n SPECCER_PHYSICAL_KEYS,\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n} from './constants';\nimport { styles } from './utils/styles';\n\n/**\n * Creates an HTML element based on the specified type.\n * *\n * @param {string} [type='tabstops'] - Type of element ('tabstops', 'landmark', 'region').\n * @param {unknown} [content] - Content to be added to the element.\n * @param {string} [n='span'] - HTML tag name (default is 'span').\n * @returns {HTMLElement} The created HTML element.\n *\n * @example\n * ```ts\n * const tabElement = create('tabstops', null, 'div');\n * const landmarkElement = create('landmark', 1, 'div');\n * const regionElement = create('region', null, 'div');\n * ```\n */\nexport const create = (\n type = 'tabstops',\n content: unknown,\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _class_names = cx('ph-speccer speccer a11y', {\n tabstops: type === 'tabstops',\n landmark: type === 'landmark',\n region: type === 'region'\n });\n\n if (type === 'landmark' && content) {\n const _text_node = document.createTextNode(content + '');\n\n _el.appendChild(_text_node);\n }\n\n setClassNames(_el, _class_names);\n\n return _el;\n};\n\n/**\n * Adds an accessibility element to the document body based on the target element and type.\n *\n * ![Screenshot of speccer a11y tab stops in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-tabstop.png?raw=true)\n * ![Screenshot of speccer a11y landmark in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-landmark.png?raw=true)\n *\n * @param {HTMLElement} targetEl - Target HTML element.\n * @param {unknown} [content] - Content to be added to the accessibility element.\n * @param {string} type - Type of accessibility element ('tabstops' or 'landmark').\n * @returns {Promise<void>} A Promise resolving when the operation is complete.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('myElement');\n * if (targetElement) {\n * await element(targetElement, 1, 'landmark');\n * await element(targetElement, null, 'tabstops');\n * }\n * ```\n */\nexport const element = async (\n targetEl: HTMLElement,\n content: unknown,\n type: string\n): Promise<void> => {\n if (!targetEl || !targetEl.checkVisibility()) return;\n\n const _a11y_el = create(type, content);\n\n if (type === 'landmark') {\n _a11y_el.setAttribute('data-speccer-nodename', targetEl.nodeName);\n\n const role =\n targetEl.role || `semantic role: ${targetEl.nodeName.toLowerCase()}`;\n const label = targetEl.getAttribute('aria-label') || 'unnamed';\n\n _a11y_el.setAttribute('title', `${label}: ${role}`);\n }\n\n document.body.appendChild(_a11y_el);\n\n const _a11y_styles = await styles(type, targetEl as HTMLElement, _a11y_el);\n\n await add(_a11y_el, _a11y_styles);\n};\n\n/**\n * Adds a shortcut element to the document body based on the provided HTML element and shortcut string.\n *\n * ![Screenshot of speccer a11y shortcuts in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-shortcut.png?raw=true)\n *\n * @param {HTMLElement} el - Target HTML element.\n * @param {string} shortcutString - Shortcut string to be displayed.\n * @returns {Promise<void>} A Promise resolving when the operation is complete.\n *\n * @example\n * ```ts\n * const shortcutElement = document.getElementById('shortcutElement');\n * if (shortcutElement) {\n * await shortcut(shortcutElement, 'Ctrl + Shift + A');\n * }\n * ```\n */\nexport const shortcut = async (\n el: HTMLElement,\n shortcutString: string\n): Promise<void> => {\n const _regex = /\\s\\+\\s/;\n const _keys = shortcutString.split(_regex).map((str) => str.trim());\n const _shortcut_holder = document.createElement('div');\n\n _shortcut_holder.classList.add('ph-speccer');\n _shortcut_holder.classList.add('speccer');\n _shortcut_holder.classList.add('a11y');\n _shortcut_holder.classList.add('shortcut-holder');\n\n for (const key of _keys) {\n const _key_element = document.createElement('kbd');\n const _key_text_node = document.createTextNode(key);\n\n _key_element.classList.add('ph-speccer');\n _key_element.classList.add('speccer');\n _key_element.classList.add('a11y');\n _key_element.classList.add('shortcut');\n\n if (SPECCER_MODIFIER_KEYS.includes(key.toLowerCase()))\n _key_element.classList.add('modifier');\n\n if (SPECCER_PHYSICAL_KEYS.includes(key.toLowerCase()))\n _key_element.classList.add('physical');\n\n _key_element.appendChild(_key_text_node);\n\n _shortcut_holder.appendChild(_key_element);\n }\n\n document.body.appendChild(_shortcut_holder);\n\n const _shortcut_holder_styles = await styles(\n 'shortcut',\n el as HTMLElement,\n _shortcut_holder\n );\n\n await add(_shortcut_holder, _shortcut_holder_styles);\n};\n\n/**\n * Initializes the accessibility elements on the document.\n *\n * @example\n * ```ts\n * init();\n * ```\n */\nexport const init = () => {\n const _tab_order_elements = document.querySelectorAll(\n '[data-speccer-a11y-tabstops]'\n );\n const _landmark_elements = document.querySelectorAll(\n '[data-speccer-a11y-landmark]'\n );\n const _shortcut_elements = document.querySelectorAll(\n '[data-speccer-a11y-shortcut]'\n );\n\n if (_shortcut_elements.length) {\n for (const el of _shortcut_elements) {\n const _shortcut_string = el.getAttribute('data-speccer-a11y-shortcut');\n\n if (!_shortcut_string || _shortcut_string === '') continue;\n\n shortcut(el as HTMLElement, _shortcut_string);\n }\n }\n\n if (_tab_order_elements.length) {\n for (const el of _tab_order_elements) {\n const _tabstops_els = el.querySelectorAll(\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n );\n\n for (const tabstopsEl of _tabstops_els) {\n element(tabstopsEl as HTMLElement, null, 'tabstops');\n }\n }\n }\n\n if (_landmark_elements.length) {\n for (const el of _landmark_elements) {\n const _landmark_els = el.querySelectorAll(\n SPECCER_LANDMARK_ELEMENTS_SELECTOR\n );\n\n for (const [landmarkIndex, landmarkEl] of _landmark_els.entries()) {\n element(landmarkEl as HTMLElement, landmarkIndex + 1, 'landmark');\n element(landmarkEl as HTMLElement, null, 'region');\n }\n }\n }\n};\n","/* eslint no-console:0 */\nimport { waitForFrame } from '../../utils/wait';\n\nconst SPECCER_DATA_ATTR = 'data-speccer-grid';\nconst SPECCER_FEATURE_GRID = 'grid';\n\n/**\n * Creates a visual grid overlay for a given target element.\n *\n * @param {HTMLElement} targetElement - The target element to create the grid overlay for.\n * @param {CSSStyleDeclaration} styles - The computed styles of the target element.\n * @returns {HTMLDivElement} The created grid container element.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * const styles = window.getComputedStyle(targetElement);\n * const gridOverlay = create(targetElement, styles);\n * document.body.appendChild(gridOverlay);\n * }\n * ```\n */\nexport const create = (\n targetElement: HTMLElement,\n styles: CSSStyleDeclaration\n) => {\n const rect = targetElement.getBoundingClientRect();\n const templateColumns = styles.gridTemplateColumns;\n const gridTemplate = styles.gridTemplate;\n // const templateRows = styles['gridTemplateRows'];// for a later feature perhaps\n const columnGap = parseInt(styles.columnGap);\n // const rowGap = styles.rowGap;// for a later feature perhaps\n const padding = styles.padding;\n const gridContainer = document.createElement('div');\n\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-gap-original',\n `${columnGap}px`\n );\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-gap',\n `${columnGap < 24 ? 24 : columnGap}px`\n );\n\n if (columnGap < 24) {\n gridContainer.classList.add('speccer-small-grid');\n }\n\n gridContainer.classList.add('ph-speccer');\n gridContainer.classList.add('speccer');\n gridContainer.classList.add('speccer-grid-container');\n\n gridContainer.style.height = rect.height + 64 + 'px';\n gridContainer.style.width = rect.width + 'px';\n gridContainer.style.left = rect.left + 'px';\n gridContainer.style.top = rect.top - 32 + 'px';\n gridContainer.style.padding = padding;\n // gridContainer.style.columnGap = `${columnGap}px`; // using css vars instead\n gridContainer.style.gridTemplate = gridTemplate;\n gridContainer.style.gridTemplateRows = 'repeat(1, 100%)';\n\n //gridContainer.style.gridTemplateRows = templateRows; // for a later feature perhaps\n const numberOfItems = templateColumns.split(' ').length;\n\n for (let i = 0; i < numberOfItems; i++) {\n const gridItem = document.createElement('div');\n\n gridItem.classList.add('ph-speccer');\n gridItem.classList.add('speccer');\n gridItem.classList.add('speccer-grid-item');\n gridContainer.appendChild(gridItem);\n }\n\n return gridContainer;\n};\n\n/**\n * Create a visual overlay to present the column gaps for a grid container\n *\n * Adds a visual grid overlay to the target element if it has the appropriate data attribute and is a grid.\n *\n * ![grid](https://github.com/phun-ky/speccer/blob/main/public/grid.png?raw=true)\n *\n * @param {HTMLElement} targetElement - The target element to add the grid overlay to.\n * @returns {Promise<void>} A promise that resolves once the overlay has been added.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * element(targetElement).then(() => {\n * console.log('Grid overlay added');\n * });\n * }\n * ```\n */\nexport const element = async (targetElement: HTMLElement): Promise<void> => {\n if (!targetElement) return;\n\n const attr = targetElement.getAttribute(SPECCER_DATA_ATTR);\n\n await waitForFrame();\n\n const styles = window.getComputedStyle(targetElement);\n\n if (\n attr === SPECCER_FEATURE_GRID &&\n (styles.display === 'grid' || styles.display.indexOf('grid') !== -1)\n ) {\n const gridContainerElement = create(targetElement, styles);\n\n document.body.appendChild(gridContainerElement);\n }\n};\n","/* eslint no-console:0 */\nimport { cx, set } from '../../utils/classnames';\nimport { getRec } from '../../utils/position';\nimport { add as addStyles } from '../../utils/styles';\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 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 * ![mark](https://github.com/phun-ky/speccer/blob/main/public/mark.png?raw=true)\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;\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/**\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 */\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { add as addStyles, get as getStyles } from '../../utils/styles';\n\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 area.split(' ').forEach((a) => {\n _extra_class_names[a] = true;\n });\n }\n\n const _class_names = cx('ph-speccer 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 * ![typography](https://github.com/phun-ky/speccer/blob/main/public/typography.png?raw=true)\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 const _use_highlighting = _area?.includes('syntax');\n\n targetEl.classList.add('is-specced');\n\n const _html = await template(targetEl, _use_highlighting);\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 * @param {boolean} [useHighlighting=false] - If we should use highlighting markup\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, true);\n * console.log(typographyStyles);\n * ```\n */\nexport const template = async (\n targetEl: HTMLElement,\n useHighlighting = false\n): Promise<string> => {\n const _target_styles = await getStyles(targetEl);\n const _styles = getTypography(_target_styles);\n\n if (useHighlighting) {\n const _fontFamily = _styles.fontFamily\n .split(',')\n .map((font) => {\n if (font.indexOf('\\'') !== -1) {\n return `<span class=\"token string\">${font}</span>`;\n }\n\n return font;\n })\n .join('<span class=\"token punctuation\">, </span>');\n const _fontSize = `<span class=\"token number\">${parseInt(_styles.fontSize, 10)}</span><span class=\"token unit\">px</span> <span class=\"token operator\">/</span> <span class=\"token number\">${\n parseInt(_styles.fontSize, 10) / 16\n }</span><span class=\"token unit\">rem</span>`;\n const _letterSpacing =\n _styles.letterSpacing.indexOf('px') !== -1\n ? `<span class=\"token number\">${parseInt(_styles.letterSpacing, 10)}</span><span class=\"token unit\">px</span>`\n : _styles.letterSpacing;\n const _lineHeight =\n _styles.lineHeight !== 'normal'\n ? `<span class=\"token number\">${parseInt(_styles.lineHeight, 10)}</span><span class=\"token unit\">px</span> <span class=\"token operator\">/</span> <span class=\"token number\">${\n parseInt(_styles.lineHeight, 10) / 16\n }</span><span class=\"token unit\">rem</span>`\n : 'normal';\n\n return `\n<pre class=\"language-css\" tabindex=\"-1\"><code class=\"language-css\"><span class=\"token selector\"><span class=\"token class\">.typography</span></span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">font-family</span><span class=\"token punctuation\">:</span> ${_fontFamily}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-size</span><span class=\"token punctuation\">:</span> ${_fontSize}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> <span class=\"token number\">${_styles.fontWeight}</span><span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-variation-settings</span><span class=\"token punctuation\">:</span> ${_styles.fontVariationSettings}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">line-height</span><span class=\"token punctuation\">:</span> ${_lineHeight}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">letter-spacing</span><span class=\"token punctuation\">:</span> ${_letterSpacing}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-style</span><span class=\"token punctuation\">:</span> ${_styles.fontStyle}<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre>`;\n }\n\n return (\n `\n` +\n 'typography: {' +\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> ${\n _styles.lineHeight !== 'normal'\n ? `${parseInt(_styles.lineHeight, 10)}px / ${parseInt(_styles.lineHeight, 10) / 16}rem`\n : 'normal'\n };</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 { SpeccerAreaEnum } from '../../../types/enums/area';\nimport { 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\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?.includes(SpeccerAreaEnum.Right)) {\n _position = {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n } else if (area?.includes(SpeccerAreaEnum.Top)) {\n _position = {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n } else if (area?.includes(SpeccerAreaEnum.Bottom)) {\n _position = {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n }\n\n return _position;\n};\n","/**\n *\n * @example\n * ```typescript\n * import '@phun-ky/speccer/dist/speccer.min.css';\n * import speccer from '@phun-ky/speccer';\n *\n * // do stuff\n * speccer();\n * ```\n * @example\n * ```html\n * <link rel=\"stylesheet\" href=\"../path/to/speccer.min.css\" />\n * <script src=\"../path/to/speccer.js\"></script>\n * ```\n * @packageDocumentation\n */\n/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport './types/interfaces/global';\nimport { dom, lazy, manual, activate } from './config/browser';\nimport { init as initA11y } from './features/a11y';\nimport {\n create as dissectCreate,\n element as dissectElement,\n dissect as _dissect\n} from './features/dissect';\nimport { create as gridCreate, element as gridElement } from './features/grid';\nimport { create as markCreate, element as markElement } from './features/mark';\nimport {\n create as measureCreate,\n element as measureElement\n} from './features/measure';\nimport {\n create as spacingCreate,\n element as spacingElement\n} from './features/spacing';\nimport {\n create as typographyCreate,\n element as typographyElement\n} from './features/typography';\nimport { removeAll } from './utils/node';\n\nexport const grid = {\n create: gridCreate,\n element: gridElement\n};\n\nexport const spacing = {\n create: spacingCreate,\n element: spacingElement\n};\n\nexport const dissect = {\n create: dissectCreate,\n element: dissectElement,\n dissect: _dissect\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('.ph-speccer.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 const SPECCER_DATA_ATTR = 'data-speccer-grid';\n const SPECCER_FEATURE_GRID = 'grid';\n const SPECCER_FEATURE_GRID_SELECTOR = `[${SPECCER_DATA_ATTR}=\"${SPECCER_FEATURE_GRID}\"]`;\n const elstToBeGrid = document.querySelectorAll(SPECCER_FEATURE_GRID_SELECTOR);\n\n for (const el of elsToBeMarked) {\n markElement(el as HTMLElement);\n }\n\n for (const el of elstToBeGrid) {\n gridElement(el as HTMLElement);\n }\n for (const el of elsToBeSpecced) {\n spacingElement(el as HTMLElement);\n }\n for (const el of elsToBeMeasured) {\n measureElement(el as HTMLElement);\n }\n for (const el of elsToBeTypographySpecced) {\n typographyElement(el as HTMLElement);\n }\n for (const el of elsToBeDissected) {\n dissectElement(el as HTMLElement);\n }\n initA11y();\n};\n\nexport default speccer;\n\nactivate(speccer);\n","/**\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|undefined|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 | undefined | null =>\n 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"],"names":["SpeccerAreaEnum","DissectAreaEnum","MeasureAreaEnum","getAreasFromString","areaString","split","isLeftArea","includes","Left","isRightArea","Right","isBottomArea","Bottom","isFullArea","Full","isEncloseArea","Enclose","isSubtle","Subtle","isParentArea","Parent","isCurly","Curly","isString","variable","isNotString","isNumber","isNotNumber","isUndefined","set","el","cls","avoid","length","trim","filter","cl","forEach","classList","add","cx","cls_obj","Object","keys","classname","join","create","textContent","area","id","n","_el","document","createElement","_text_node","createTextNode","_extra_class_names","appendChild","setAttribute","_class_names","setClassNames","uniqueID","Math","random","toString","substring","waitForFrame","Promise","requestAnimationFrame","coords","rect","top","left","width","height","xy","center","x","y","right","bottom","intrinsic_coords","async","pos","Error","_allowed_positions","_el_rect","getBoundingClientRect","styles","Array","isArray","constructor","style","key","value","get","getComputedStyle","DrawCircle","canvas","circle","radius","areas","this","init","body","contains","getElementById","html","documentElement","max","scrollHeight","offsetHeight","clientHeight","addStyle","draw","_circle_el_id","createElementNS","_el_ID","getAttribute","round","window","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","options","direct","firstSet","direction","firstControl","lastControl","firstPoint","lastPoint","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","scrollTop","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","DrawSVGCurlyBracket","originalPathElement","startElement","stopElement","firstPathElement","secondPathElement","connect","getPathElement","path","_path_el_id","_new_path","cloneNode","dataStartElID","remove","_first_path_element","_second_path_element","parentNode","insertBefore","nextSibling","_direction","path1pos1","path1pos2","path2pos1","path2pos2","getPositionsForCurlySVGPath","_first_path_d","_second_path_d","DrawSVGLine","line","getPositionsForSVGPath","_d","getSVGPath","SPECCER_LITERALS","getNumberValue","parseInt","getClassNameFromCSSProperty","property","replace","pinSpace","getPropertyValue","hasStylePropertySet","element","getParentWithStylePropertySet","parentElement","get_horizontal_center_of_els","modifier","startRect","targetRect","get_vertical_center_of_els","offset","targetEl","_target_rect","_el_offset_top","scrollY","_el_offset_left","scrollX","stickyParentElement","getParentThatIsSticky","isTargetSticky","isSticky","originalPosition","position","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","dissectionEl","SPECCER_PIN_SPACE","SPECCER_MEASURE_SIZE","_positional_styles","dissect","symbol","_areas_string","Outline","_dissection_el_id","str","toLowerCase","ltr","idx","toUpperCase","_dissection_el","_dissection_styles","isParent","SVG","_index_to_use","sectionEl","_dissection_els","querySelectorAll","targetIndex","_character_to_use","_literals_to_use","getCharacterToUse","dissectionIterator","text","tag","_target_styles","getStyles","display","opacity","visibility","Width","_measure_el","addStyles","SPECCER_DEFAULT_MEASURE_SIZE","Height","isHeightArea","spacingEl","_text_content","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","getSpacing","_target_pruned_spacing_styles","_value","_speccer_el","_class_name","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","SPECCER_MODIFIER_KEYS","SPECCER_PHYSICAL_KEYS","type","a11yEl","content","checkVisibility","_a11y_el","tabstops","landmark","region","nodeName","role","label","_a11y_styles","shortcut","shortcutString","_keys","map","_shortcut_holder","_key_element","_key_text_node","_shortcut_holder_styles","targetElement","templateColumns","gridTemplateColumns","gridTemplate","columnGap","padding","gridContainer","setProperty","gridTemplateRows","numberOfItems","i","gridItem","attr","indexOf","gridContainerElement","markElement","classNames","elementToMark","positionalStyles","markStyles","decimal","number","decimals","parseFloat","toFixed","a","innerHTML","_area","_use_highlighting","_html","useHighlighting","_styles","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","getTypography","_fontFamily","font","_fontSize","_letterSpacing","_lineHeight","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","grid","gridCreate","gridElement","spacing","spacingCreate","spacingElement","dissectCreate","_dissect","measure","measureCreate","mark","markCreate","typography","typographyCreate","typographyElement","modes","selector","call","e","removeAll","elsToBeSpecced","elsToBeMeasured","elsToBeTypographySpecced","elsToBeDissected","elsToBeMarked","elstToBeGrid","_tab_order_elements","_landmark_elements","_shortcut_elements","_shortcut_string","_tabstops_els","tabstopsEl","_landmark_els","landmarkIndex","landmarkEl","entries","initA11y"],"mappings":"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"}
1
+ {"version":3,"file":"speccer.esm.js","sources":["../src/types/enums/area.ts","../src/utils/area.ts","../src/utils/typeof/index.ts","../src/utils/classnames.ts","../src/features/dissect/utils/create.ts","../src/utils/id.ts","../src/utils/wait.ts","../src/utils/coords.ts","../src/utils/xy.ts","../src/utils/intrinsic-coords.ts","../src/utils/styles.ts","../src/utils/classes/DrawCircle.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/DrawSVGCurlyBracket.ts","../src/utils/classes/DrawSVGLine.ts","../src/utils/constants.ts","../src/utils/css.ts","../src/utils/style-property.ts","../src/utils/position.ts","../src/features/dissect/utils/styles.ts","../src/features/dissect/utils/dissect.ts","../src/utils/camel-case.ts","../src/features/dissect/utils/get-character-to-use.ts","../src/features/dissect/index.ts","../src/features/measure/index.ts","../src/features/spacing/utils/position.ts","../src/features/spacing/index.ts","../src/utils/resize.ts","../src/utils/debounce.ts","../src/config/browser.ts","../src/features/a11y/constants/index.ts","../src/features/a11y/utils/styles.ts","../src/features/a11y/index.ts","../src/features/grid/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/main.ts","../src/utils/node.ts"],"sourcesContent":["/* 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 Parent = 'parent', // Represents a parent area\n Enclose = 'enclose', // Represents an enclose area\n Subtle = 'subtle', // Represents an subtle 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 'subtle' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'subtle' is present, otherwise `false`.\n */\nexport const isSubtle = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Subtle);\n};\n\n/**\n * Checks if 'parent' area is present in the provided areaString.\n *\n * @param areaString - The string containing areas.\n * @returns `true` if 'parent' is present, otherwise `false`.\n */\nexport const isParentArea = (areaString: string): boolean => {\n const areas = getAreasFromString(areaString);\n\n return areas.includes(DissectAreaEnum.Parent);\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\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-disable import/no-unused-modules */\n/**\n * Checks if the given variable is a string.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a string, false otherwise.\n */\nexport const isString = (variable: unknown): boolean =>\n typeof variable === 'string';\n\n/**\n * Checks if the given variable is not a string.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a string, false otherwise.\n */\nexport const isNotString = (variable: unknown): boolean => !isString(variable);\n\n/**\n * Checks if the given variable is a number.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a number, false otherwise.\n */\nexport const isNumber = (variable: unknown): boolean =>\n typeof variable === 'number';\n\n/**\n * Checks if the given variable is not a number.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a number, false otherwise.\n */\nexport const isNotNumber = (variable: unknown): boolean => !isNumber(variable);\n\n/**\n * Checks if the given variable is a boolean.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is a boolean, false otherwise.\n */\nexport const isBoolean = (variable: unknown): boolean =>\n typeof variable === 'boolean';\n\n/**\n * Checks if the given variable is not a boolean.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not a boolean, false otherwise.\n */\nexport const isNotBoolean = (variable: unknown): boolean =>\n !isBoolean(variable);\n\n/**\n * Checks if the given variable is undefined.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is undefined, false otherwise.\n */\nexport const isUndefined = (variable: unknown): boolean =>\n typeof variable === 'undefined';\n\n/**\n * Checks if the given variable is not undefined.\n *\n * @param {unknown} variable - The variable to check.\n * @returns {boolean} True if the variable is not undefined, false otherwise.\n */\nexport const isNotUndefined = (variable: unknown): boolean =>\n !isUndefined(variable);\n","/* eslint no-console:0 */\nimport {\n ClassNamesFirstArgType,\n ClassNamesSecondArgType\n} from '../types/interfaces/classnames';\n\nimport { isNotString } from './typeof';\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.add(cl.trim()));\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.toggle(cl.trim()));\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)) return;\n\n cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .forEach((cl) => el.classList.remove(cl.trim()));\n};\n\n/**\n * Combines class names and optional properties object into a single string of class names.\n *\n * The `cx` function takes two parameters: `cls` and `cls_obj`.\n * The `cls` parameter can be either a string representing class names or an object with\n * properties set to `true` or `false`. The `cls_obj` parameter is an optional object with\n * properties set to `true` or `false`, allowing for conditional inclusion of class names.\n *\n * @param {ClassNamesFirstArgType} cls - The class names as a string or an object with properties set to true or false.\n * @param {ClassNamesObjectMapInterface} cls_obj - An optional object with properties set to true or false to conditionally include class names.\n * @returns {string} - Returns a single string containing the combined 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: ClassNamesFirstArgType,\n cls_obj?: ClassNamesSecondArgType\n): string => {\n if (!cls) return '';\n\n if (!cls_obj && isNotString(cls))\n return Object.keys(cls)\n .filter((classname) => cls[classname])\n .join(' ')\n .trim();\n\n return `${(cls as string).trim()} ${\n cls_obj\n ? Object.keys(cls_obj)\n .filter((classname) => cls_obj[classname])\n .join(' ')\n : ''\n }`.trim();\n};\n","import {\n isCurly,\n isEncloseArea,\n isFullArea,\n isParentArea,\n isSubtle\n} from '../../../utils/area';\nimport { set as setClassNames, cx } from '../../../utils/classnames';\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} id - The id of the dissection element\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 id = '',\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _text_node = document.createTextNode(textContent);\n const _extra_class_names: Record<string, boolean> = {};\n\n if (area !== null && area !== '') _extra_class_names[area] = true;\n\n if (\n isParentArea(area) &&\n !isFullArea(area) &&\n !isCurly(area) &&\n !isSubtle(area)\n )\n _extra_class_names.svg = true;\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 const _class_names = cx('ph-speccer speccer dissection', _extra_class_names);\n\n setClassNames(_el, _class_names);\n\n _el.setAttribute('id', id);\n\n return _el;\n};\n","/* eslint no-console:0 */\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 * 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","/**\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 { SpeccerCoordinatesInterface } from '../types/xy';\n\nimport { 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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\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 {SpeccerCoordinatesInterface} 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): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftCoordinates = xy.left(rect);\n * // leftCoordinates.x and leftCoordinates.y will contain the coordinates\n * ```\n */\n left: (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.center_y(rect)\n }),\n 'right-top': (rect: DOMRect) => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the right bottom of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the right bottom.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightBottomCoordinates = xy['right-bottom'](rect);\n * // rightBottomCoordinates.x and rightBottomCoordinates.y will contain the coordinates\n * ```\n */\n 'right-bottom': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left top of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left top.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftTop = xy['left-top'](rect);\n * // leftTop.x and leftTop.y will contain the coordinates\n * ```\n */\n 'left-top': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the left bottom of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left bottom.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftBottomCoordinates = xy['left-bottom'](rect);\n * // leftBottomCoordinates.x and leftBottomCoordinates.y will contain the coordinates\n * ```\n */\n 'left-bottom': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the top left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the top left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topLeftCoordinates = xy['top-left'](rect);\n * // topLeftCoordinates.x and topLeftCoordinates.y will contain the coordinates\n * ```\n */\n 'top-left': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the top right of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the top right.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topRightCoordinates = xy['top-right'](rect);\n * // topRightCoordinates.x and topRightCoordinates.y will contain the coordinates\n * ```\n */\n 'top-right': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.top(rect)\n }),\n /**\n * Get the x and y coordinates of the bottom left of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the bottom left.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomLeftCoordinates = xy['bottom-left'](rect);\n * // bottomLeftCoordinates.x and bottomLeftCoordinates.y will contain the coordinates\n * ```\n */\n 'bottom-left': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the bottom right of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the bottom right.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomRight = xy['bottom-right'](rect);\n * // bottomRight.x and bottomRight.y will contain the coordinates\n * ```\n */\n 'bottom-right': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.bottom(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the top center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const topCenterCoordinates = xy['top-center'](rect);\n * // topCenterCoordinates.x and topCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'top-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.top(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the right center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const rightCenterCoordinates = xy['right-center'](rect);\n * // rightCenterCoordinates.x and rightCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'right-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.right(rect),\n y: coords.center_y(rect)\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 {SpeccerCoordinatesInterface} The x and y coordinates of the bottom center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const bottomCenterCoordinates = xy['bottom-center'](rect);\n * // bottomCenterCoordinates.x and bottomCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'bottom-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.center_x(rect),\n y: coords.bottom(rect)\n }),\n /**\n * Get the x and y coordinates of the left center of a DOMRect.\n * @param {DOMRect} rect - The DOMRect to retrieve the coordinates from.\n * @returns {SpeccerCoordinatesInterface} The x and y coordinates of the left center.\n * @example\n * ```ts\n * const rect = element.getBoundingClientRect();\n * const leftCenterCoordinates = xy['left-center'](rect);\n * // leftCenterCoordinates.x and leftCenterCoordinates.y will contain the coordinates\n * ```\n */\n 'left-center': (rect: DOMRect): SpeccerCoordinatesInterface => ({\n x: coords.left(rect),\n y: coords.center_y(rect)\n })\n};\n","import { isNotString } from './typeof';\nimport { 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) throw Error('No position given');\n\n if (isNotString(pos))\n throw Error(\n `The position given is not the required type: pos: ${typeof pos}`\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 Error(\n `The position given does not match allowed positions to use! Valid positions are: ${_allowed_positions.join(\n ', '\n )}`\n );\n\n await waitForFrame();\n\n const _el_rect = el.getBoundingClientRect();\n\n return xy[pos](_el_rect);\n};\n","/* eslint no-console:0 */\nimport { isBoolean, isNumber, isString } from './typeof';\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 | { 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 | { key: string; value: string }[]\n): Promise<void> => {\n if (\n !el ||\n !styles ||\n isString(styles) ||\n isNumber(styles) ||\n isBoolean(styles) ||\n (Array.isArray(styles) && !styles.length) ||\n (!Object.keys(styles).length && styles.constructor === Object)\n )\n return;\n\n await waitForFrame();\n\n if (Array.isArray(styles))\n for (const style of styles) {\n el.style[style.key] = style.value;\n }\n else\n for (const key of Object.keys(styles)) {\n 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 { isBottomArea, isLeftArea, isRightArea } from '../area';\nimport { uniqueID } from '../id';\nimport { intrinsic_coords } from '../intrinsic-coords';\nimport { add as addStyle } from '../styles';\n\n/**\n * Class representing a DrawCircle instance.\n */\nexport class DrawCircle {\n #canvas: HTMLElement | SVGElement | null;\n el: HTMLElement;\n circle: SVGCircleElement;\n radius: number;\n areas: string;\n\n /**\n * Creates a new DrawCircle instance.\n * @param el - The element used to position the circle.\n * @param radius - The radius of the circle\n * @param areas - The areas used to identify position\n */\n constructor(el: HTMLElement, radius: number, areas: string) {\n this.#init(el, radius, areas);\n }\n\n /**\n * Initializes the DrawCircle instance.\n * @param el - The element used to position the circle.\n * @param radius - The radius of the circle\n * * @param areas - The areas used to identify position\n * @throws Will throw an error if required elements are missing or not in the DOM.\n */\n #init(el: HTMLElement, radius: number, areas: string) {\n if (!el || !radius || !areas) {\n throw new Error('Missing inputs el or radius or areas');\n }\n\n if (!document.body.contains(el)) {\n throw new Error('el is not in the DOM');\n }\n\n this.el = el;\n this.radius = radius;\n this.areas = areas;\n\n this.#canvas = document.getElementById('ph-speccer-svg');\n\n if (!this.#canvas) {\n throw new Error(\n 'Missing required SVG element to draw circles. Please see the documentation'\n );\n }\n\n const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\n });\n\n this.draw();\n }\n\n /**\n * Draws the circle based on the provided el and radius.\n */\n async draw() {\n const _id = uniqueID();\n const _circle_el_id = `ph_draw-circle-${_id}`;\n\n this.circle = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'circle'\n ) as unknown as SVGCircleElement;\n\n const _el_ID = this.el.getAttribute('id') || uniqueID();\n\n this.el.setAttribute('id', _el_ID);\n\n this.circle.setAttribute('id', _circle_el_id);\n this.circle.setAttribute('data-el', _el_ID);\n this.circle.classList.add('ph-speccer');\n this.circle.classList.add('speccer');\n this.circle.classList.add('circle');\n\n if (this.#canvas) {\n this.#canvas.appendChild(this.circle);\n } else {\n throw new Error('No parentNode found for circle');\n }\n\n let pos = 'top';\n\n if (isLeftArea(this.areas)) pos = 'left';\n\n if (isRightArea(this.areas)) pos = 'right';\n\n if (isBottomArea(this.areas)) pos = 'bottom';\n\n const { x, y } = await intrinsic_coords(this.el, pos);\n\n this.circle.setAttribute('r', this.radius + ''); // SVG attributes\n this.circle.setAttribute('cx', Math.round(x) + ''); // SVG attributes\n this.circle.setAttribute('cy', Math.round(y) + ''); // SVG attributes\n this.circle.setAttribute('fill', 'currentColor'); // SVG attributes\n }\n}\n\n// Exporting the class as a global object (if needed)\nwindow.DrawCircle = DrawCircle;\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) throw Error('No element given');\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';\n\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') y2modifier = 8;\n else if (direction === 'west') x2modifier = 8;\n else if (direction === 'east') x2modifier = -8;\n else if (direction === 'south') y2modifier = -8;\n\n const { firstPoint, firstControl, lastControl, lastPoint } =\n createBezierCurveCoordinates(\n {\n x1: x1 + x1modifier,\n x2: x2 + x2modifier,\n y1: y1 + y1modifier + document.documentElement.scrollTop,\n y2: y2 + y2modifier + document.documentElement.scrollTop\n },\n {\n direct: true,\n firstSet,\n direction\n }\n );\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 { firstPoint, firstControl, lastControl, lastPoint } =\n createBezierCurveCoordinates({ x1, x2, y1, y2 }, { direction: '' });\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","import { isNotNumber, isUndefined } from './typeof';\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 (isUndefined(cx) || isUndefined(cy) || isUndefined(ex) || isUndefined(ey))\n throw new SyntaxError('Missing input for `angle`');\n\n if (isNotNumber(cx) || isNotNumber(cy) || isNotNumber(ex) || isNotNumber(ey))\n throw 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 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; // range [0, 360)\n\n return theta;\n};\n","/* eslint no-console:0 */\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) return 'east';\n\n if (degrees >= 22.5 && degrees <= 67.5) return 'south-east';\n\n if (degrees >= 67.5 && degrees <= 112.5) return 'south';\n\n if (degrees >= 112.5 && degrees <= 157.5) return 'south-west';\n\n if (degrees >= 157.5 && degrees <= 202.5) return 'west';\n\n if (degrees >= 202.5 && degrees <= 247.5) return 'north-west';\n\n if (degrees >= 247.5 && degrees <= 292.5) return 'north';\n\n if (degrees >= 292.5 && degrees <= 337.5) return 'north-east';\n\n return 'east';\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) return 'south';\n\n if (degrees > 135 && degrees <= 225) return 'west';\n\n if (degrees > 225 && degrees <= 315) return 'north';\n\n return 'east';\n};\n","import { getCurlySVGPath, getPositionsForCurlySVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\nimport { uniqueID } from '../id';\nimport { add as addStyle } from '../styles';\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 const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\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 const dataStartElID = this.startElement.getAttribute('id') || uniqueID();\n\n this.startElement.setAttribute('id', dataStartElID);\n _new_path.setAttribute('data-start-el', dataStartElID);\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 { getPositionsForSVGPath, getSVGPath } from '../bezier';\nimport { direction_of_element } from '../direction-of-element';\nimport { uniqueID } from '../id';\nimport { add as addStyle } from '../styles';\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 const body = document.body;\n const html = document.documentElement;\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n addStyle(this.#canvas, {\n height: `${height}px`\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 const dataStartElID = this.startElement.getAttribute('id') || uniqueID();\n\n this.startElement.setAttribute('id', dataStartElID);\n\n _new_path.setAttribute('id', _path_el_id);\n _new_path.setAttribute('data-start-el', dataStartElID);\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","/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\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: string[] = [...'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: string[] = [\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: number =\n 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: number =\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 */\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\n\nimport {\n SPECCER_DEFAULT_PIN_SPACE,\n SPECCER_DEFAULT_MEASURE_SIZE,\n SPECCER_DEFAULT_LINE_WIDTH\n} from './constants';\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(String(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.includes('Top')) return property.replace('Top', ' top');\n\n if (property.includes('Right')) return property.replace('Right', ' right');\n\n if (property.includes('Bottom')) return property.replace('Bottom', ' bottom');\n\n if (property.includes('Left')) return property.replace('Left', ' left');\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","import { waitForFrame } from './wait';\n\n/**\n * Checks if a specific CSS property of an element has a certain value.\n *\n * @param {HTMLElement} element - The target element.\n * @param {string} property - The CSS property to check.\n * @param {string} value - The expected value of the CSS property.\n * @returns {Promise<boolean>} - A promise that resolves to true if the property has the expected value, false otherwise.\n *\n * @example\n * ```ts\n * // Usage example:\n * const result = await hasStylePropertySet(myElement, 'display', 'block');\n * console.log(result); // true or false\n * ```\n */\nconst hasStylePropertySet = async (\n element: HTMLElement,\n property: string,\n value: string\n): Promise<boolean> => {\n await waitForFrame();\n\n const _computed_style = getComputedStyle(element);\n\n return _computed_style[property] === value;\n};\n/**\n * Finds the nearest parent element with a specific CSS property set to a certain value.\n *\n * @param {HTMLElement} element - The target element.\n * @param {string} property - The CSS property to check.\n * @param {string} value - The expected value of the CSS property.\n * @returns {Promise<HTMLElement | null>} - A promise that resolves to the parent element if found, or null if none.\n *\n * @example\n * ```ts\n * // Usage example:\n * const parentSticky = await getParentWithStylePropertySet(myElement, 'position', 'sticky');\n * console.log(parentSticky); // HTMLElement or null\n * ```\n */\nconst getParentWithStylePropertySet = async (\n element: HTMLElement,\n property: string,\n value: string\n): Promise<HTMLElement | null> => {\n if (!element.parentElement) return null;\n\n const hasStyleProperty = await hasStylePropertySet(\n element.parentElement,\n property,\n value\n );\n\n if (hasStyleProperty) return element.parentElement;\n\n return await getParentWithStylePropertySet(\n element.parentElement,\n property,\n value\n );\n};\n\n/**\n * Finds the nearest parent element with 'position: sticky'.\n *\n * @param {HTMLElement} element - The target element.\n * @returns {Promise<HTMLElement | null>} - A promise that resolves to the sticky parent element if found, or null if none.\n * @private\n * @example\n * ```ts\n * // Usage example:\n * const stickyParent = await getParentThatIsSticky(myElement);\n * console.log(stickyParent); // HTMLElement or null\n * ```\n */\nexport const getParentThatIsSticky = async (\n element: HTMLElement\n): Promise<HTMLElement | null> => {\n return await getParentWithStylePropertySet(element, 'position', 'sticky');\n};\n\n/**\n * Checks if an element has 'position: sticky'.\n *\n * @param {HTMLElement} element - The target element.\n * @returns {Promise<boolean>} - A promise that resolves to true if the element has 'position: sticky', false otherwise.\n *\n * @example\n * ```ts\n * // Usage example:\n * const isElementSticky = await isSticky(myElement);\n * console.log(isElementSticky); // true or false\n * ```\n */\nexport const isSticky = async (element: HTMLElement): Promise<boolean> =>\n await hasStylePropertySet(element, 'position', 'sticky');\n","import { GetRecPropertiesInterface } from '../types/interfaces/position';\nimport { PositionPropertiesType, PositionInputType } from '../types/position';\n\nimport { getParentThatIsSticky, isSticky } from './style-property';\nimport { waitForFrame } from './wait';\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 let _target_rect = targetEl.getBoundingClientRect();\n let _el_offset_top = _target_rect.top + window.scrollY;\n\n const _el_offset_left = _target_rect.left + window.scrollX;\n const stickyParentElement = await getParentThatIsSticky(targetEl);\n const isTargetSticky = await isSticky(targetEl);\n\n // if node is sticky, we need to account for that\n if (isTargetSticky) {\n const originalPosition = targetEl.style.position;\n\n await waitForFrame();\n targetEl.style.position = 'relative';\n\n await waitForFrame();\n _target_rect = targetEl.getBoundingClientRect();\n _el_offset_top = _target_rect.top;\n targetEl.style.position = originalPosition;\n }\n // If any of the parents are sticky, we need to account for that\n else if (stickyParentElement) {\n const originalPosition = stickyParentElement.style.position;\n\n await waitForFrame();\n stickyParentElement.style.position = 'relative';\n\n await waitForFrame();\n _target_rect = targetEl.getBoundingClientRect();\n _el_offset_top = _target_rect.top;\n stickyParentElement.style.position = originalPosition;\n }\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 top: _target_offset.top,\n left: _target_offset.left,\n height: _target_height,\n width: _target_width\n }),\n toTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromTop: ({\n center = false,\n sourceHeight = _source_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toBottom: ({\n center = false,\n sourceHeight = _source_height,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromBottom: ({\n center = false,\n targetHeight = _target_height,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromLeft: ({\n center = false,\n sourceWidth = _source_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 toRight: ({\n center = false,\n sourceWidth = _source_width,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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 fromRight: ({\n center = false,\n targetWidth = _target_width,\n modifier = 0\n }: PositionInputType = {}): PositionPropertiesType => ({\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","import { DissectStylesOptionsType } from '../../../types/bezier';\nimport { SpeccerStylesReturnType } from '../../../types/styles';\nimport {\n isBottomArea,\n isEncloseArea,\n isFullArea,\n isLeftArea,\n isParentArea,\n isRightArea,\n isSubtle\n} from '../../../utils/area';\nimport { pinSpace, measureSize } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\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 {HTMLElement} parentElement - The parent element.\n * @param {DissectStylesOptionsType} options - Optional styles options.\n * @returns {Promise<SpeccerStylesReturnType>} - The computed styles.\n *\n * @example\n * ```ts\n * const area = 'top-left';\n * const targetElement = document.getElementById('target');\n * const parentElement = document.getElementById('parent');\n * const dissectionElement = document.getElementById('dissection');\n * const options = { isCurly: true };\n * const styles = await styles(area, targetElement, dissectionElement, parentElement, options);\n * console.log(styles);\n * ```\n */\nexport const styles = async (\n area: string,\n targetEl: HTMLElement,\n dissectionEl: HTMLElement,\n parentElement: HTMLElement,\n options?: DissectStylesOptionsType\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\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 (isParentArea(area) && !isFullArea(area) && !isCurly && !isSubtle(area)) {\n if (isRightArea(area)) {\n const { top } = _positional_styles.fromRight({\n center: true\n });\n\n await waitForFrame();\n\n const { left, width } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left + width + SPECCER_PIN_SPACE}px`,\n top: `${top}px`\n };\n }\n\n if (isBottomArea(area)) {\n const { left } = _positional_styles.toBottom({\n center: true\n });\n\n await waitForFrame();\n\n const { top, height } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left}px`,\n top: `${top + height + SPECCER_PIN_SPACE}px`\n };\n }\n\n if (isLeftArea(area)) {\n const { top } = _positional_styles.fromLeft({\n center: true\n });\n\n await waitForFrame();\n\n const { left } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left - SPECCER_PIN_SPACE * 1.5}px`,\n top: `${top}px`\n };\n }\n\n const { left } = _positional_styles.fromTop({\n center: true\n });\n\n await waitForFrame();\n\n const { top } = parentElement.getBoundingClientRect();\n\n return {\n left: `${left}px`,\n top: `${top - SPECCER_PIN_SPACE * 1.5}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 }\n\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\n 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 }\n\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\n 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 }\n\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\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 }\n\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","import { DissectAreaEnum } from '../../../types/enums/area';\nimport {\n isCurly,\n isEncloseArea,\n isFullArea,\n isParentArea,\n isSubtle,\n useSVG\n} from '../../../utils/area';\nimport { camelCase } from '../../../utils/camel-case';\nimport { DrawCircle } from '../../../utils/classes/DrawCircle';\nimport { DrawSVGCurlyBracket } from '../../../utils/classes/DrawSVGCurlyBracket';\nimport { DrawSVGLine } from '../../../utils/classes/DrawSVGLine';\nimport { uniqueID } from '../../../utils/id';\nimport { add } from '../../../utils/styles';\n\nimport { create } from './create';\nimport { styles } from './styles';\n\n/**\n * Create and style the dissection element as needed.\n *\n * This function appends a new dissection element to the document body based on the anatomy data attribute\n * of the target element. It handles different styles, such as curly brackets or lines, based on the anatomy type.\n *\n * @param {HTMLElement} el - The target element that contains the anatomy data.\n * @param {string} symbol - The symbol to use.\n * @param {HTMLElement} parentElement - The parent element\n * @param {string} [areas] - Optional areas to use if not [data-anatomy] is set as an attribute on the element\n * @returns {Promise<string|void>} A promise that resolves to the id of the dissection element when the dissection is completed, or `void` if required input is invalid.\n *\n * @example\n * ```ts\n * const element = document.getElementById('target');\n * const symbol = 0;\n * dissect(element, symbol).then(() => {\n * console.log('Dissection completed');\n * });\n * ```\n */\nexport const dissect = async (\n el: HTMLElement,\n symbol: string,\n parentElement: HTMLElement,\n areas = ''\n): Promise<string | void> => {\n if (!el) return;\n\n const _areas_string: string = el.getAttribute('data-anatomy') || areas;\n\n if (\n !_areas_string ||\n _areas_string === '' ||\n !_areas_string.includes(DissectAreaEnum.Outline)\n )\n return;\n\n const _dissection_el_id = `speccer-${camelCase(_areas_string)}-${el.getAttribute('id') || uniqueID()}`;\n const _dissection_el = create(symbol, _areas_string, _dissection_el_id);\n\n el.setAttribute('data-speccer-element-id', _dissection_el_id);\n\n document.body.appendChild(_dissection_el);\n\n const _dissection_styles = await styles(\n _areas_string,\n el as HTMLElement,\n _dissection_el,\n parentElement,\n {\n isCurly: isCurly(_areas_string)\n }\n );\n\n await add(_dissection_el, _dissection_styles);\n\n const isParent =\n isParentArea(_areas_string) &&\n !isEncloseArea(_areas_string) &&\n !isFullArea(_areas_string) &&\n !isSubtle(_areas_string);\n const isSVGLine =\n isParent || (useSVG(_areas_string) && !isCurly(_areas_string));\n\n if (isSVGLine) {\n new DrawSVGLine(el as HTMLElement, _dissection_el);\n\n if (isParent) new DrawCircle(el, 5, _areas_string);\n } else if (isCurly(_areas_string)) {\n new DrawSVGCurlyBracket(el as HTMLElement, _dissection_el);\n }\n\n return _dissection_el_id;\n};\n","/**\n * Converts a string to camel case.\n * @param {string} str - The input string.\n * @returns {string} - The string converted to camel case.\n */\nexport const camelCase = (str: string): string =>\n str\n .normalize('NFKD') // split accented characters into their base characters and diacritical marks\n .replace(/[\\u0300-\\u036f]/g, '') // remove all the accents, which happen to be all in the \\u03xx UNICODE block.\n .trim() // trim leading or trailing whitespace\n .toLowerCase() // convert to lowercase\n .replace(/[^a-z0-9 -]/g, '') // remove non-alphanumeric characters\n .replace(/\\s+/g, ' ')\n .replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (ltr, idx) =>\n idx === 0 ? ltr.toLowerCase() : ltr.toUpperCase()\n )\n .replace(/\\s+/g, '');\n","import { SPECCER_LITERALS } from '../../../utils/constants';\n\nlet _index_to_use = 0;\n\n/**\n * Returns the character to use at the specified target index.\n * If the index exceeds the available characters, it generates a new character by pairing uppercase and lowercase letters.\n *\n * @param {number} targetIndex - The index of the character to retrieve.\n * @returns {string} The character to use at the specified index.\n *\n * @example\n * ```ts\n * const character = getCharacterToUse(0); // Returns first character from SPECCER_LITERALS\n * const nextCharacter = getCharacterToUse(25); // Returns next character or a generated pair if index exceeds literals length\n * ```\n */\nexport const getCharacterToUse = (targetIndex: number): string => {\n const _literals_to_use = window.SPECCER_LITERALS || SPECCER_LITERALS;\n\n let _character_to_use = _literals_to_use[targetIndex];\n\n // Reset index to use when we start new elements\n if (targetIndex === 0) _index_to_use = 0;\n\n /**\n * If we're running out of characters to use,\n * make a new one with uppercase and lowercase pairs\n */\n if (!_character_to_use) {\n _character_to_use = `${_literals_to_use[_index_to_use]}${_literals_to_use[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n return _character_to_use;\n};\n","/**\n * This feature highlights the anatomy of an element.\n *\n * ![dissect](https://github.com/phun-ky/speccer/blob/main/public/anatomy.png?raw=true)\n *\n * In your component examples, use the following attribute. Remember to use the `data-anatomy-section` as an attribute on a parent element to scope the marking.\n *\n * @example\n * ```html\n * <div data-anatomy-section>\n * <div\n * data-anatomy=\"outline [full|enclose][curly] [left|right|top|bottom]\"\n * class=\"...\"\n * ></div>\n * </div>\n * ```\n *\n * @packageDocumentation\n */\n// eslint-disable-next-line import/no-unused-modules\nexport { create } from './utils/create';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { dissect } from './utils/dissect';\n\nimport { dissect as dissectionIterator } from './utils/dissect';\nimport { getCharacterToUse } from './utils/get-character-to-use';\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 = async (sectionEl: HTMLElement): Promise<void> => {\n if (!sectionEl) return;\n\n const _dissection_els = sectionEl.querySelectorAll('[data-anatomy]');\n\n if (!_dissection_els || _dissection_els.length === 0) return;\n\n _dissection_els.forEach(\n async (targetEl: HTMLElement, targetIndex: number): Promise<void> => {\n const _character_to_use = getCharacterToUse(targetIndex);\n\n await dissectionIterator(targetEl, _character_to_use, sectionEl);\n }\n );\n};\n","/* eslint no-console:0 */\nimport {\n isBottomArea,\n isHeightArea,\n isRightArea,\n isWidthArea\n} from '../../utils/area';\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DEFAULT_MEASURE_SIZE_NEG } from '../../utils/constants';\nimport { getRec } from '../../utils/position';\nimport { get as getStyles, add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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(String(text), 10)}px`);\n\n setClassNames(_el, `ph-speccer 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 * ![measure](https://github.com/phun-ky/speccer/blob/main/public/measure.png?raw=true)\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) 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 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","import { offset } from '../../../utils/position';\nimport { add as addStyles } from '../../../utils/styles';\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 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 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 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 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 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 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 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","/* eslint no-console:0 */\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';\n\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(String(text));\n\n _el.appendChild(_text_content);\n _el.setAttribute('title', `${text}px`);\n setClassNames(_el, 'ph-speccer 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 * ![spacing](https://github.com/phun-ky/speccer/blob/main/public/spacing.png?raw=true)\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 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) return;\n\n for (const property of _target_pruned_spacing_styles) {\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 { 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 }] */\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) clearTimeout(timeout);\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/**\n * Contains the helper functions to activate SPECCER via a script tag, based on attributes:\n *\n * > [!NOTE]\n * > If the activation method is dom or instant, a resize feature is activated, making sure everything is re-rendered on resize. for manual or lazy loading, you are responsible to handle resize yourself.\n *\n * > [!NOTE]\n * > Remember to add the CSS file!:\n *\n * > ```html\n * > <link rel=\"stylesheet\" href=\"../path/to/speccer.min.css\" />\n * > ```\n *\n * ## Default implementation\n * ```html\n * <script src=\"../speccer.js\"</script>\n * ```\n *\n * If no attribute is applied, it will default to `data-dom`, as in, it will initialize when `DOMContentLoaded` is fired.\n *\n * ## Manual initiation\n * ```html\n * <script src=\"../speccer.js\" data-manual</script>\n * ```\n *\n * Makes `window.speccer()` available to be used when you feel like it\n *\n * ## Initiate immediately\n * ```html\n * <script src=\"../speccer.js\" data-instant></script>\n * ```\n *\n * fires off `speccer()` right away\n *\n * ## Initiate when dom ready\n * ```html\n * <script src=\"../speccer.js\" data-dom></script>\n * ```\n *\n * Waits for `DOMContentLoaded`\n *\n * ## Initiate with lazy loading\n * ```html\n * <script src=\"../speccer.js\" data-lazy></script>\n * ```\n *\n * Lazy loads `speccer()` per specced element\n *\n * @packageDocumentation\n */\nimport { element as dissectElement } from '../features/dissect';\nimport { element as measureElement } from '../features/measure';\nimport { element as specElement } from '../features/spacing';\nimport { SpeccerFunctionType } from '../types/speccer';\nimport { activate as resizeActivate } from '../utils/resize';\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 // `DOMContentLoaded` already fired\n else speccer();\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 for (const el of els) {\n if (el.intersectionRatio > 0) {\n specElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n '[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)'\n )) {\n _spec_observer.observe(el);\n }\n\n const _measure_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n measureElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll('[data-speccer-measure]')) {\n _measure_observer.observe(el);\n }\n\n const _dissect_observer = new IntersectionObserver(async (els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n await dissectElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll('[data-anatomy-section]')) {\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 (_speccer_script_src?.includes('speccer.js')) {\n if (_script.hasAttribute('data-manual')) manual(speccer);\n else if (_script.hasAttribute('data-instant')) speccer();\n else if (_script.hasAttribute('data-dom')) dom(speccer);\n else if (_script.hasAttribute('data-lazy')) lazy();\n else dom(speccer);\n\n if (\n !_script.hasAttribute('data-manual') &&\n !_script.hasAttribute('data-lazy')\n )\n resizeActivate(speccer);\n }\n }\n};\n","/**\n * Array of keys considered as modifiers in shortcuts.\n * @type {string[]}\n */\nexport const SPECCER_MODIFIER_KEYS: string[] = [\n 'alt',\n 'altgraph',\n 'capslock',\n 'control',\n 'fn',\n 'fnlock',\n 'hyper',\n 'meta',\n 'numlock',\n 'os',\n 'scrolllock',\n 'shift',\n 'super',\n 'symbol',\n 'command',\n 'ctrl',\n 'altgr',\n 'symbollock'\n];\n\nexport const SPECCER_PHYSICAL_KEYS: string[] = [\n 'escape',\n 'esc',\n 'enter',\n 'return',\n '⏎',\n '␛'\n];\n\n/**\n * Selector string for tabbable elements.\n * @type {string}\n */\nexport const SPECCER_TABBABLE_ELEMENTS_SELECTOR = `\n a[href], area[href], input:not([disabled]):not([tabindex='-1']),\n button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']),\n textarea:not([disabled]):not([tabindex='-1']),\n iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]\n`;\n\n/**\n * Selector string for landmark elements.\n * @type {string}\n */\nexport const SPECCER_LANDMARK_ELEMENTS_SELECTOR = `\nheader, footer, section, main, nav, aside, [role=\"section\"], [role=\"banner\"],\n[role=\"complementary\"], [role=\"contentinfo\"], [role=\"form\"], [role=\"main\"],\n[role=\"navigation\"], [role=\"region\"], [role=\"search\"]\n`;\n","import { SpeccerStylesReturnType } from '../../../types/styles';\nimport { pinSpace } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Calculates and returns the styles for an accessibility element based on its type.\n *\n * @param {string} type - Type of the accessibility element ('tabstops', 'landmark', 'region', 'shortcut', or default).\n * @param {HTMLElement} targetEl - Target HTML element.\n * @param {HTMLElement} a11yEl - Accessibility HTML element to be styled.\n * @returns {Promise<SpeccerStylesReturnType>} A Promise resolving with the calculated styles.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('targetElement');\n * const a11yElement = document.createElement('div');\n *\n * // Example for tab order element styles\n * const tabstopsStyles = await styles('tabstops', targetElement, a11yElement);\n *\n * // Example for landmark element styles\n * const landmarkStyles = await styles('landmark', targetElement, a11yElement);\n *\n * // Example for region element styles\n * const regionStyles = await styles('region', targetElement, a11yElement);\n *\n * // Example for shortcut element styles\n * const shortcutStyles = await styles('shortcut', targetElement, a11yElement);\n *\n * // Example for default styles\n * const defaultStyles = await styles('default', targetElement, a11yElement);\n * ```\n */\nexport const styles = async (\n type: string,\n targetEl: HTMLElement,\n a11yEl: HTMLElement\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const SPECCER_PIN_SPACE = pinSpace(a11yEl);\n const _positional_styles = await getRec(a11yEl, targetEl);\n\n if (type === 'tabstops') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 32;\n\n if (left <= 0) left = 32;\n\n if (top <= 0) top = 32;\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'landmark') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 16;\n top -= 16;\n\n if (left <= 0) left = 32;\n\n if (top <= 0) top = 32;\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'region') {\n const { left, top, height, width } = _positional_styles.fromTop();\n\n return {\n height: `${height}px`,\n width: `${width}px`,\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n if (type === 'shortcut') {\n const { left, top } = _positional_styles.fromBottom();\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n }\n\n const { left, top } = _positional_styles.fromTop({\n center: true,\n modifier: SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left - 32}px`,\n top: `${top - 32}px`\n };\n};\n","/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { add } from '../../utils/styles';\n\nimport {\n SPECCER_LANDMARK_ELEMENTS_SELECTOR,\n SPECCER_MODIFIER_KEYS,\n SPECCER_PHYSICAL_KEYS,\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n} from './constants';\nimport { styles } from './utils/styles';\n\n/**\n * Creates an HTML element based on the specified type.\n * *\n * @param {string} [type='tabstops'] - Type of element ('tabstops', 'landmark', 'region').\n * @param {unknown} [content] - Content to be added to the element.\n * @param {string} [n='span'] - HTML tag name (default is 'span').\n * @returns {HTMLElement} The created HTML element.\n *\n * @example\n * ```ts\n * const tabElement = create('tabstops', null, 'div');\n * const landmarkElement = create('landmark', 1, 'div');\n * const regionElement = create('region', null, 'div');\n * ```\n */\nexport const create = (\n type = 'tabstops',\n content: unknown,\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _class_names = cx('ph-speccer speccer a11y', {\n tabstops: type === 'tabstops',\n landmark: type === 'landmark',\n region: type === 'region'\n });\n\n if (type === 'landmark' && content) {\n const _text_node = document.createTextNode(String(content));\n\n _el.appendChild(_text_node);\n }\n\n setClassNames(_el, _class_names);\n\n return _el;\n};\n\n/**\n * Adds an accessibility element to the document body based on the target element and type.\n *\n * ![Screenshot of speccer a11y tab stops in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-tabstop.png?raw=true)\n * ![Screenshot of speccer a11y landmark in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-landmark.png?raw=true)\n *\n * @param {HTMLElement} targetEl - Target HTML element.\n * @param {unknown} [content] - Content to be added to the accessibility element.\n * @param {string} type - Type of accessibility element ('tabstops' or 'landmark').\n * @returns {Promise<void>} A Promise resolving when the operation is complete.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('myElement');\n * if (targetElement) {\n * await element(targetElement, 1, 'landmark');\n * await element(targetElement, null, 'tabstops');\n * }\n * ```\n */\nexport const element = async (\n targetEl: HTMLElement,\n content: unknown,\n type: string\n): Promise<void> => {\n if (!targetEl || !targetEl.checkVisibility()) return;\n\n const _a11y_el = create(type, content);\n\n if (type === 'landmark') {\n _a11y_el.setAttribute('data-speccer-nodename', targetEl.nodeName);\n\n const role =\n targetEl.role || `semantic role: ${targetEl.nodeName.toLowerCase()}`;\n const label = targetEl.getAttribute('aria-label') || 'unnamed';\n\n _a11y_el.setAttribute('title', `${label}: ${role}`);\n }\n\n document.body.appendChild(_a11y_el);\n\n const _a11y_styles = await styles(type, targetEl as HTMLElement, _a11y_el);\n\n await add(_a11y_el, _a11y_styles);\n};\n\n/**\n * Adds a shortcut element to the document body based on the provided HTML element and shortcut string.\n *\n * ![Screenshot of speccer a11y shortcuts in use](https://github.com/phun-ky/speccer/blob/main/public/a11y-shortcut.png?raw=true)\n *\n * @param {HTMLElement} el - Target HTML element.\n * @param {string} shortcutString - Shortcut string to be displayed.\n * @returns {Promise<void>} A Promise resolving when the operation is complete.\n *\n * @example\n * ```ts\n * const shortcutElement = document.getElementById('shortcutElement');\n * if (shortcutElement) {\n * await shortcut(shortcutElement, 'Ctrl + Shift + A');\n * }\n * ```\n */\nexport const shortcut = async (\n el: HTMLElement,\n shortcutString: string\n): Promise<void> => {\n const _regex = /\\s\\+\\s/;\n const _keys = shortcutString.split(_regex).map((str) => str.trim());\n const _shortcut_holder = document.createElement('div');\n\n _shortcut_holder.classList.add('ph-speccer');\n _shortcut_holder.classList.add('speccer');\n _shortcut_holder.classList.add('a11y');\n _shortcut_holder.classList.add('shortcut-holder');\n\n for (const key of _keys) {\n const _key_element = document.createElement('kbd');\n const _key_text_node = document.createTextNode(key);\n\n _key_element.classList.add('ph-speccer');\n _key_element.classList.add('speccer');\n _key_element.classList.add('a11y');\n _key_element.classList.add('shortcut');\n\n if (SPECCER_MODIFIER_KEYS.includes(key.toLowerCase()))\n _key_element.classList.add('modifier');\n\n if (SPECCER_PHYSICAL_KEYS.includes(key.toLowerCase()))\n _key_element.classList.add('physical');\n\n _key_element.appendChild(_key_text_node);\n\n _shortcut_holder.appendChild(_key_element);\n }\n\n document.body.appendChild(_shortcut_holder);\n\n const _shortcut_holder_styles = await styles(\n 'shortcut',\n el as HTMLElement,\n _shortcut_holder\n );\n\n await add(_shortcut_holder, _shortcut_holder_styles);\n};\n\n/**\n * Initializes the accessibility elements on the document.\n *\n * @example\n * ```ts\n * init();\n * ```\n */\nexport const init = () => {\n const _tab_order_elements = document.querySelectorAll(\n '[data-speccer-a11y-tabstops]'\n );\n const _landmark_elements = document.querySelectorAll(\n '[data-speccer-a11y-landmark]'\n );\n const _shortcut_elements = document.querySelectorAll(\n '[data-speccer-a11y-shortcut]'\n );\n\n if (_shortcut_elements.length) {\n for (const el of _shortcut_elements) {\n const _shortcut_string = el.getAttribute('data-speccer-a11y-shortcut');\n\n if (!_shortcut_string || _shortcut_string === '') continue;\n\n shortcut(el as HTMLElement, _shortcut_string);\n }\n }\n\n if (_tab_order_elements.length) {\n for (const el of _tab_order_elements) {\n const _tabstops_els = el.querySelectorAll(\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n );\n\n for (const tabstopsEl of _tabstops_els) {\n element(tabstopsEl as HTMLElement, null, 'tabstops');\n }\n }\n }\n\n if (_landmark_elements.length) {\n for (const el of _landmark_elements) {\n const _landmark_els = el.querySelectorAll(\n SPECCER_LANDMARK_ELEMENTS_SELECTOR\n );\n\n for (const [landmarkIndex, landmarkEl] of _landmark_els.entries()) {\n element(landmarkEl as HTMLElement, landmarkIndex + 1, 'landmark');\n element(landmarkEl as HTMLElement, null, 'region');\n }\n }\n }\n};\n","/* eslint no-console:0 */\nimport { waitForFrame } from '../../utils/wait';\n\nconst SPECCER_DATA_ATTR = 'data-speccer-grid';\nconst SPECCER_FEATURE_GRID = 'grid';\n\n/**\n * Creates a visual grid overlay for a given target element.\n *\n * @param {HTMLElement} targetElement - The target element to create the grid overlay for.\n * @param {CSSStyleDeclaration} styles - The computed styles of the target element.\n * @returns {Promise<HTMLDivElement>} The created grid container element.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * const styles = window.getComputedStyle(targetElement);\n * const gridOverlay = create(targetElement, styles);\n * document.body.appendChild(gridOverlay);\n * }\n * ```\n */\nexport const create = async (\n targetElement: HTMLElement,\n styles: CSSStyleDeclaration\n): Promise<HTMLDivElement> => {\n await waitForFrame();\n\n const { height, width, top, left } = targetElement.getBoundingClientRect();\n const { gridTemplateColumns, gridTemplate, padding } = styles;\n // const templateRows = styles['gridTemplateRows'];// for a later feature perhaps\n const columnGap = parseInt(styles.columnGap);\n // const rowGap = styles.rowGap;// for a later feature perhaps\n const gridContainer = document.createElement('div');\n\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-gap-original',\n `${columnGap}px`\n );\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-gap',\n `${columnGap < 24 ? 24 : columnGap}px`\n );\n\n if (columnGap < 24) gridContainer.classList.add('speccer-small-grid');\n\n gridContainer.classList.add('ph-speccer');\n gridContainer.classList.add('speccer');\n gridContainer.classList.add('speccer-grid-container');\n\n gridContainer.style.height = `${height + 64}px`;\n gridContainer.style.width = `${width}px`;\n gridContainer.style.left = `${left}px`;\n gridContainer.style.top = `${top - 32}px`;\n gridContainer.style.padding = padding;\n // gridContainer.style.columnGap = `${columnGap}px`; // using css vars instead\n gridContainer.style.gridTemplate = gridTemplate;\n gridContainer.style.gridTemplateRows = 'repeat(1, 100%)';\n\n //gridContainer.style.gridTemplateRows = templateRows; // for a later feature perhaps\n const numberOfItems = gridTemplateColumns.split(' ').length;\n\n for (let i = 0; i < numberOfItems; i++) {\n const gridItem = document.createElement('div');\n\n gridItem.classList.add('ph-speccer');\n gridItem.classList.add('speccer');\n gridItem.classList.add('speccer-grid-item');\n gridContainer.appendChild(gridItem);\n }\n\n return gridContainer;\n};\n\n/**\n * Create a visual overlay to present the column gaps for a grid container\n *\n * Adds a visual grid overlay to the target element if it has the appropriate data attribute and is a grid.\n *\n * ![grid](https://github.com/phun-ky/speccer/blob/main/public/grid.png?raw=true)\n *\n * @param {HTMLElement} targetElement - The target element to add the grid overlay to.\n * @returns {Promise<void>} A promise that resolves once the overlay has been added.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * element(targetElement).then(() => {\n * console.log('Grid overlay added');\n * });\n * }\n * ```\n */\nexport const element = async (targetElement: HTMLElement): Promise<void> => {\n if (!targetElement) return;\n\n const attr = targetElement.getAttribute(SPECCER_DATA_ATTR);\n\n await waitForFrame();\n\n const styles = window.getComputedStyle(targetElement);\n\n if (\n attr === SPECCER_FEATURE_GRID &&\n (styles.display === 'grid' || styles.display.includes('grid'))\n ) {\n const gridContainerElement = await create(targetElement, styles);\n\n document.body.appendChild(gridContainerElement);\n }\n};\n","/* eslint no-console:0 */\nimport { cx, set } from '../../utils/classnames';\nimport { getRec } from '../../utils/position';\nimport { add as addStyles } from '../../utils/styles';\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 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 * ![mark](https://github.com/phun-ky/speccer/blob/main/public/mark.png?raw=true)\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;\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/**\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(String(number)).toFixed(decimals);\n","/* eslint no-console:0 */\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { add as addStyles, get as getStyles } from '../../utils/styles';\n\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 for (const a of area.split(' ')) {\n _extra_class_names[a] = true;\n }\n }\n\n const _class_names = cx('ph-speccer 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 * ![typography](https://github.com/phun-ky/speccer/blob/main/public/typography.png?raw=true)\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 const _use_highlighting = _area?.includes('syntax');\n\n targetEl.classList.add('is-specced');\n\n const _html = await template(targetEl, _use_highlighting);\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 * @param {boolean} [useHighlighting=false] - If we should use highlighting markup\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, true);\n * console.log(typographyStyles);\n * ```\n */\nexport const template = async (\n targetEl: HTMLElement,\n useHighlighting = false\n): Promise<string> => {\n const _target_styles = await getStyles(targetEl);\n const _styles = getTypography(_target_styles);\n\n if (useHighlighting) {\n const _fontFamily = _styles.fontFamily\n .split(',')\n .map((font) => {\n if (font.includes('\\''))\n return `<span class=\"token string\">${font}</span>`;\n\n return font;\n })\n .join('<span class=\"token punctuation\">, </span>');\n const _fontSize = `<span class=\"token number\">${parseInt(_styles.fontSize, 10)}</span><span class=\"token unit\">px</span> <span class=\"token operator\">/</span> <span class=\"token number\">${\n parseInt(_styles.fontSize, 10) / 16\n }</span><span class=\"token unit\">rem</span>`;\n const _letterSpacing = _styles.letterSpacing.includes('px')\n ? `<span class=\"token number\">${parseInt(_styles.letterSpacing, 10)}</span><span class=\"token unit\">px</span>`\n : _styles.letterSpacing;\n const _lineHeight =\n _styles.lineHeight !== 'normal'\n ? `<span class=\"token number\">${parseInt(_styles.lineHeight, 10)}</span><span class=\"token unit\">px</span> <span class=\"token operator\">/</span> <span class=\"token number\">${\n parseInt(_styles.lineHeight, 10) / 16\n }</span><span class=\"token unit\">rem</span>`\n : 'normal';\n\n return `\n<pre class=\"language-css\" tabindex=\"-1\"><code class=\"language-css\"><span class=\"token selector\"><span class=\"token class\">.typography</span></span> <span class=\"token punctuation\">{</span>\n <span class=\"token property\">font-family</span><span class=\"token punctuation\">:</span> ${_fontFamily}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-size</span><span class=\"token punctuation\">:</span> ${_fontSize}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> <span class=\"token number\">${_styles.fontWeight}</span><span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-variation-settings</span><span class=\"token punctuation\">:</span> ${_styles.fontVariationSettings}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">line-height</span><span class=\"token punctuation\">:</span> ${_lineHeight}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">letter-spacing</span><span class=\"token punctuation\">:</span> ${_letterSpacing}<span class=\"token punctuation\">;</span>\n <span class=\"token property\">font-style</span><span class=\"token punctuation\">:</span> ${_styles.fontStyle}<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre>`;\n }\n\n return (\n `\n` +\n 'typography: {' +\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> ${\n _styles.lineHeight !== 'normal'\n ? `${parseInt(_styles.lineHeight, 10)}px / ${parseInt(_styles.lineHeight, 10) / 16}rem`\n : 'normal'\n };</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 { SpeccerAreaEnum } from '../../../types/enums/area';\nimport { 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\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 if (area?.includes(SpeccerAreaEnum.Right))\n return {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n\n if (area?.includes(SpeccerAreaEnum.Top))\n return {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n\n if (area?.includes(SpeccerAreaEnum.Bottom))\n return {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n\n return {\n left: _left_layout_position_left,\n top: _left_layout_position_top\n };\n};\n","/**\n *\n * @example\n * ```typescript\n * import '@phun-ky/speccer/dist/speccer.min.css';\n * import speccer from '@phun-ky/speccer';\n *\n * // do stuff\n * speccer();\n * ```\n * @example\n * ```html\n * <link rel=\"stylesheet\" href=\"../path/to/speccer.min.css\" />\n * <script src=\"../path/to/speccer.js\"></script>\n * ```\n * @packageDocumentation\n */\n/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport './types/interfaces/global';\nimport { dom, lazy, manual, activate } from './config/browser';\nimport { init as initA11y } from './features/a11y';\nimport {\n create as dissectCreate,\n element as dissectElement,\n dissect as _dissect\n} from './features/dissect';\nimport { create as gridCreate, element as gridElement } from './features/grid';\nimport { create as markCreate, element as markElement } from './features/mark';\nimport {\n create as measureCreate,\n element as measureElement\n} from './features/measure';\nimport {\n create as spacingCreate,\n element as spacingElement\n} from './features/spacing';\nimport {\n create as typographyCreate,\n element as typographyElement\n} from './features/typography';\nimport { removeAll } from './utils/node';\n\nexport const grid = {\n create: gridCreate,\n element: gridElement\n};\n\nexport const spacing = {\n create: spacingCreate,\n element: spacingElement\n};\n\nexport const dissect = {\n create: dissectCreate,\n element: dissectElement,\n dissect: _dissect\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('.ph-speccer.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 const SPECCER_DATA_ATTR = 'data-speccer-grid';\n const SPECCER_FEATURE_GRID = 'grid';\n const SPECCER_FEATURE_GRID_SELECTOR = `[${SPECCER_DATA_ATTR}=\"${SPECCER_FEATURE_GRID}\"]`;\n const elstToBeGrid = document.querySelectorAll(SPECCER_FEATURE_GRID_SELECTOR);\n\n for (const el of elsToBeMarked) {\n markElement(el as HTMLElement);\n }\n\n for (const el of elstToBeGrid) {\n gridElement(el as HTMLElement);\n }\n for (const el of elsToBeSpecced) {\n spacingElement(el as HTMLElement);\n }\n for (const el of elsToBeMeasured) {\n measureElement(el as HTMLElement);\n }\n for (const el of elsToBeTypographySpecced) {\n typographyElement(el as HTMLElement);\n }\n for (const el of elsToBeDissected) {\n dissectElement(el as HTMLElement);\n }\n initA11y();\n};\n\nexport default speccer;\n\nactivate(speccer);\n","/**\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|undefined|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 | undefined | null =>\n 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"],"names":["SpeccerAreaEnum","DissectAreaEnum","MeasureAreaEnum","getAreasFromString","areaString","split","isLeftArea","includes","Left","isRightArea","Right","isBottomArea","Bottom","isFullArea","Full","isEncloseArea","Enclose","isSubtle","Subtle","isParentArea","Parent","isCurly","Curly","isString","variable","isNotString","isNumber","isNotNumber","isUndefined","set","el","cls","avoid","length","trim","filter","cl","forEach","classList","add","cx","cls_obj","Object","keys","classname","join","create","textContent","area","id","n","_el","document","createElement","_text_node","createTextNode","_extra_class_names","svg","appendChild","setAttribute","_class_names","setClassNames","uniqueID","Math","random","toString","substring","waitForFrame","Promise","requestAnimationFrame","coords","rect","top","left","width","height","xy","center","x","y","right","bottom","intrinsic_coords","async","pos","Error","_allowed_positions","_el_rect","getBoundingClientRect","styles","Array","isArray","constructor","style","key","value","get","getComputedStyle","DrawCircle","canvas","circle","radius","areas","this","init","body","contains","getElementById","html","documentElement","max","scrollHeight","offsetHeight","clientHeight","addStyle","draw","_circle_el_id","createElementNS","_el_ID","getAttribute","round","window","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","options","direct","firstSet","direction","firstControl","lastControl","firstPoint","lastPoint","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","scrollTop","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","DrawSVGCurlyBracket","originalPathElement","startElement","stopElement","firstPathElement","secondPathElement","connect","getPathElement","path","_path_el_id","_new_path","cloneNode","dataStartElID","remove","_first_path_element","_second_path_element","parentNode","insertBefore","nextSibling","_direction","path1pos1","path1pos2","path2pos1","path2pos2","getPositionsForCurlySVGPath","_first_path_d","_second_path_d","DrawSVGLine","line","getPositionsForSVGPath","_d","getSVGPath","SPECCER_LITERALS","getNumberValue","parseInt","getClassNameFromCSSProperty","property","replace","pinSpace","getPropertyValue","hasStylePropertySet","element","getParentWithStylePropertySet","parentElement","get_horizontal_center_of_els","modifier","startRect","targetRect","get_vertical_center_of_els","offset","targetEl","_target_rect","_el_offset_top","scrollY","_el_offset_left","scrollX","stickyParentElement","getParentThatIsSticky","isTargetSticky","isSticky","originalPosition","position","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","dissectionEl","SPECCER_PIN_SPACE","SPECCER_MEASURE_SIZE","_positional_styles","dissect","symbol","_areas_string","Outline","_dissection_el_id","str","toLowerCase","ltr","idx","toUpperCase","_dissection_el","_dissection_styles","isParent","SVG","_index_to_use","sectionEl","_dissection_els","querySelectorAll","targetIndex","_character_to_use","_literals_to_use","getCharacterToUse","dissectionIterator","text","tag","String","_target_styles","getStyles","display","opacity","visibility","Width","_measure_el","addStyles","SPECCER_DEFAULT_MEASURE_SIZE","Height","isHeightArea","spacingEl","_text_content","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","getSpacing","_target_pruned_spacing_styles","_value","_speccer_el","_class_name","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","SPECCER_MODIFIER_KEYS","SPECCER_PHYSICAL_KEYS","type","a11yEl","content","checkVisibility","_a11y_el","tabstops","landmark","region","nodeName","role","label","_a11y_styles","shortcut","shortcutString","_keys","map","_shortcut_holder","_key_element","_key_text_node","_shortcut_holder_styles","targetElement","gridTemplateColumns","gridTemplate","padding","columnGap","gridContainer","setProperty","gridTemplateRows","numberOfItems","i","gridItem","attr","gridContainerElement","markElement","classNames","elementToMark","positionalStyles","markStyles","decimal","number","decimals","parseFloat","toFixed","a","innerHTML","_area","_use_highlighting","_html","useHighlighting","_styles","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","getTypography","_fontFamily","font","_fontSize","_letterSpacing","_lineHeight","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","grid","gridCreate","gridElement","spacing","spacingCreate","spacingElement","dissectCreate","_dissect","measure","measureCreate","mark","markCreate","typography","typographyCreate","typographyElement","modes","selector","call","e","removeAll","elsToBeSpecced","elsToBeMeasured","elsToBeTypographySpecced","elsToBeDissected","elsToBeMarked","elstToBeGrid","_tab_order_elements","_landmark_elements","_shortcut_elements","_shortcut_string","_tabstops_els","tabstopsEl","_landmark_els","landmarkIndex","landmarkEl","entries","initA11y"],"mappings":"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"}