@phun-ky/speccer 11.2.4 → 11.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/speccer.esm.js +1 -1
- package/dist/speccer.esm.js.map +1 -1
- package/dist/speccer.js +1 -1
- package/dist/speccer.js.map +1 -1
- package/package.json +13 -16
package/dist/speccer.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speccer.esm.js","sources":["../src/utils/typeof/index.ts","../src/utils/classnames.ts","../src/utils/constants.ts","../src/types/enums/area.ts","../src/utils/area.ts","../src/utils/get-options.ts","../src/utils/camel-case.ts","../src/utils/id.ts","../src/utils/node.ts","../src/utils/wait.ts","../src/utils/style-property.ts","../src/utils/position.ts","../src/utils/styles.ts","../src/features/grid/index.ts","../src/features/mark/index.ts","../src/features/measure/index.ts","../src/features/pin/utils/create-pin-element.ts","../src/utils/coords.ts","../src/utils/xy.ts","../src/utils/intrinsic-coords.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/css.ts","../src/features/pin/utils/styles.ts","../src/features/pin/utils/pin-element.ts","../src/features/pin/utils/get-character-to-use.ts","../src/features/pin/index.ts","../src/features/pin/utils/get-content-for-pin.ts","../src/features/spacing/index.ts","../src/features/spacing/utils/position.ts","../src/utils/number.ts","../src/features/typography/index.ts","../src/features/typography/utils/template.ts","../src/features/typography/utils/position.ts","../src/utils/resize.ts","../src/utils/debounce.ts","../src/config/browser.ts","../src/features/a11y/constants/index.ts","../src/features/a11y/utils/styles.ts","../src/features/a11y/utils/add-a11y-element.ts","../src/features/a11y/utils/create-a11y-element.ts","../src/features/a11y/utils/get-role.ts","../src/features/a11y/utils/add-shortcut-element.ts","../src/utils/remove-speccer-element.ts","../src/main.ts","../src/features/a11y/index.ts"],"sourcesContent":["/* 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'): void => {\n if (!el) return;\n\n if (!cls || (cls && !cls.length)) return;\n\n const preparedClassNames = cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .map((cl) => cl.trim());\n\n el.classList.add(...preparedClassNames);\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 const preparedClassNames = cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .map((cl) => cl.trim());\n\n el.classList.remove(...preparedClassNames);\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","/* 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\n/**\n * The name of the attribute speccer uses to identify elements to spec\n * @type {string}\n */\nexport const SPECCER_DATA_ATTRIBUTE = 'data-speccer';\n\n/**\n * The selector for the `spacing` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_SPACING = 'spacing';\n\n/**\n * The selector for the `measure` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_MEASURE = 'measure';\n\n/**\n * The selector for the `typography` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_TYPOGRAPHY = 'typography';\n\n/**\n * The selector for the `mark` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_MARK = 'mark';\n\n/**\n * The selector for the `grid` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_GRID = 'grid';\n\n/**\n * The selector for the container of the `pin` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_PIN_AREA = 'pin-area';\n","/* eslint-disable no-unused-vars */\n\n/**\n * Enum representing different areas in Speccer.\n */\nexport enum SpeccerAreaEnum {\n Empty = '', // Represents an empty area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom', // Represents the bottom area\n Top = 'top' // Represents the top area\n}\n\n/**\n * Enum representing different areas for the pin feature.\n */\nexport enum PinAreaEnum {\n Pin = 'pin', // Represents an pin area\n Parent = 'parent', // Represents a parent area\n Text = 'text', // Represents a text area\n Enclose = 'enclose', // Represents an enclose area\n Subtle = 'subtle', // Represents an subtle area\n Bracket = 'bracket', // Represents a bracket 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 Measure = 'measure', // Represents the measure area\n Slim = 'slim', // Represents the slim measurement area\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\n/**\n * Enum representing different typography areas.\n */\nexport enum TypographyAreaEnum {\n Typography = 'typography', // Represents the typography area\n Syntax = 'syntax', // Represents the syntax area\n Left = 'left', // Represents the left typography area\n Right = 'right', // Represents the right typography area\n Bottom = 'bottom', // Represents the bottom typography area\n Top = 'top' // Represents the top typography area\n}\n\n/**\n * Enum representing different spacing areas.\n */\nexport enum SpacingAreaEnum {\n Spacing = 'spacing' // Represents the spacing area\n}\n\n/**\n * Enum representing different mark areas.\n */\nexport enum MarkAreaEnum {\n Mark = 'mark' // Represents the mark area\n}\n\n/**\n * Enum representing different grid areas.\n */\nexport enum GridAreaEnum {\n Grid = 'grid' // Represents the grid area\n}\n","import {\n PinAreaEnum,\n MeasureAreaEnum,\n TypographyAreaEnum,\n SpacingAreaEnum,\n MarkAreaEnum,\n GridAreaEnum\n} from '../types/enums/area';\n\n/**\n * Splits a string containing areas into an array of strings.\n *\n * @param {string} 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 {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'left' is present, otherwise `false`.\n */\nexport const isLeftArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Left);\n};\n\n/**\n * Checks if 'right' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'right' is present, otherwise `false`.\n */\nexport const isRightArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Right);\n};\n\n/**\n * Checks if 'top' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'top' is present, otherwise `false`.\n */\nexport const isTopArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Top);\n};\n\n/**\n * Checks if 'bottom' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'bottom' is present, otherwise `false`.\n */\nexport const isBottomArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Bottom);\n};\n\n/**\n * Checks if 'bracket' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'bracket' is present, otherwise `false`.\n */\nexport const isBracketArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Bracket);\n};\n\n/**\n * Checks if 'enclose' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'enclose' is present, otherwise `false`.\n */\nexport const isEncloseArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Enclose);\n};\n\n/**\n * Checks if 'subtle' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'subtle' is present, otherwise `false`.\n */\nexport const isSubtle = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Subtle);\n};\n\n/**\n * Checks if 'parent' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'parent' is present, otherwise `false`.\n */\nexport const isParentArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Parent);\n};\n\n/**\n * Checks if 'text' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'text' is present, otherwise `false`.\n */\nexport const isTextArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Text);\n};\n\n/**\n * Checks if 'height' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'height' is present, otherwise `false`.\n */\nexport const isHeightArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Height);\n};\n\n/**\n * Checks if 'slim' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'slim' is present, otherwise `false`.\n */\nexport const isSlimArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Slim);\n};\n\n/**\n * Checks if 'width' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'width' is present, otherwise `false`.\n */\nexport const isWidthArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\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 {string|null} areaString - The string containing areas.\n * @returns boolean `true` if any SVG-related area is present, otherwise `false`.\n */\nexport const useSVG = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return (\n ((isParentArea(areaString) &&\n !isEncloseArea(areaString) &&\n !isBracketArea(areaString)) ||\n isTextArea(areaString) ||\n areas.includes(PinAreaEnum.SVG)) &&\n !isCurly(areaString)\n );\n};\n\n/**\n * Checks if the provided areaString contains 'curly' and 'bracket' areas.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if both 'curly' and 'bracket' are present, otherwise `false`.\n */\nexport const isCurly = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return (\n areas.includes(PinAreaEnum.Curly) && areas.includes(PinAreaEnum.Bracket)\n );\n};\n\n/**\n * Checks if the provided areaString contains 'typography'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'typography' are present, otherwise `false`.\n */\nexport const isValidTypographyElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(TypographyAreaEnum.Typography);\n\n/**\n * Checks if the provided areaString contains 'spacing'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'spacing' are present, otherwise `false`.\n */\nexport const isValidSpacingElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(SpacingAreaEnum.Spacing);\n\n/**\n * Checks if the provided areaString contains 'measure'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'measure' are present, otherwise `false`.\n */\nexport const isValidMeasureElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(MeasureAreaEnum.Measure);\n\n/**\n * Checks if the provided areaString contains 'pin'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'pin' are present, otherwise `false`.\n */\nexport const isValidPinElement = (areaString: string | null): boolean =>\n areaString !== null && areaString.split(' ').includes(PinAreaEnum.Pin);\n\n/**\n * Checks if the provided areaString contains 'mark'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'mark' are present, otherwise `false`.\n */\nexport const isValidMarkElement = (areaString: string | null): boolean =>\n areaString !== null && areaString.split(' ').includes(MarkAreaEnum.Mark);\n\n/**\n * Checks if the provided areaString contains 'grid'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @param {CSSStyleDeclaration} areaString - The string containing areas.\n * @returns boolean `true` if 'grid' are present, otherwise `false`.\n */\nexport const isValidGridElement = (\n areaString: string | null,\n styles: CSSStyleDeclaration\n): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(GridAreaEnum.Grid) &&\n (styles.display === 'grid' || styles.display.includes('grid'));\n\n/**\n * Checks if the provided areaString contains 'syntax'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if both 'syntax' are present, otherwise `false`.\n */\nexport const useSyntaxHighlighting = (areaString: string | null): boolean => {\n if (areaString)\n return areaString.split(' ').includes(TypographyAreaEnum.Syntax);\n\n return false;\n};\n","import {\n SpeccerFeatureType,\n SpeccerOptionsInterface,\n SpeccerPositionType\n} from '../types/speccer';\n\nimport {\n isBottomArea,\n isBracketArea,\n isCurly,\n isEncloseArea,\n isHeightArea,\n isLeftArea,\n isParentArea,\n isRightArea,\n isSlimArea,\n isSubtle,\n isTextArea,\n isValidGridElement,\n isValidMarkElement,\n isValidMeasureElement,\n isValidPinElement,\n isValidSpacingElement,\n isValidTypographyElement,\n isWidthArea,\n useSVG,\n useSyntaxHighlighting\n} from './area';\nimport { camelCase } from './camel-case';\n\n/**\n * Determines the Speccer feature type based on the given area string and target element.\n *\n * @param {string} areaString - The string representing different area types.\n * @param {CSSStyleDeclaration} targetStyle - The target HTML element being evaluated.\n * @returns {SpeccerFeatureType} The determined Speccer feature type.\n *\n * @example\n * ```ts\n * const feature = getFeatureBasedOnArea('left right pin', document.getElementById('myElement'));\n * console.log(feature); // Output: 'pin'\n * ```\n */\nconst getFeatureBasedOnArea = (\n areaString: string,\n targetStyle: CSSStyleDeclaration\n): SpeccerFeatureType => {\n if (isValidPinElement(areaString)) return 'pin';\n\n if (isValidGridElement(areaString, targetStyle)) return 'grid';\n\n if (isValidMarkElement(areaString)) return 'mark';\n\n if (isValidMeasureElement(areaString)) return 'measure';\n\n if (isValidSpacingElement(areaString)) return 'spacing';\n\n if (isValidTypographyElement(areaString)) return 'typography';\n\n return 'pin';\n};\nconst getPositionBasedOnArea = (areaString: string): SpeccerPositionType => {\n if (isLeftArea(areaString)) return 'left';\n\n if (isRightArea(areaString)) return 'right';\n\n if (isBottomArea(areaString)) return 'bottom';\n\n return 'top';\n};\nconst getGridToggleValue = (areaString: string) => {\n if (areaString?.includes('columns')) return 'columns';\n\n if (areaString?.includes('rows')) return 'rows';\n\n return 'both';\n};\nconst getSpacingToggleValue = (areaString: string) => {\n if (areaString?.includes('margin')) return 'margin';\n\n if (areaString?.includes('padding')) return 'padding';\n\n return 'both';\n};\n\n/**\n * Generates Speccer options based on the target element and the specified area string.\n *\n * @param {HTMLElement} targetElement - The HTML element for which options are being generated.\n * @param {string} areaString - The string representing different area types.\n * @param {SpeccerOptionsInterface|undefined} [customOptions] - Custom options\n * @returns {SpeccerOptionsInterface} The generated Speccer options.\n *\n * @example\n * ```ts\n * const options = getOptions(document.getElementById('myElement'), 'left right pin');\n * console.log(options);\n * // Output: { position: { left: true, right: true, top: false, bottom: false }, type: 'pin', pin: { bracket: false, enclose: false, subtle: false, parent: false, text: false, useSVGLine: false, useCurlyBrackets: false } }\n * ```\n */\nexport const getOptions = (\n areaString: string,\n targetStyle: CSSStyleDeclaration,\n customOptions?: SpeccerOptionsInterface | undefined\n): SpeccerOptionsInterface => {\n const type = getFeatureBasedOnArea(areaString, targetStyle);\n const options: SpeccerOptionsInterface = {\n slug: camelCase(areaString),\n position: getPositionBasedOnArea(areaString),\n type\n };\n\n if (type === 'pin') {\n options['pin'] = {\n bracket: isBracketArea(areaString),\n enclose: isEncloseArea(areaString),\n subtle: isSubtle(areaString),\n parent: isParentArea(areaString),\n text: isTextArea(areaString),\n useSVGLine: useSVG(areaString),\n useCurlyBrackets: isCurly(areaString)\n };\n }\n\n if (type === 'measure') {\n options['measure'] = {\n slim: isSlimArea(areaString),\n height: isHeightArea(areaString),\n width: isWidthArea(areaString)\n };\n }\n\n if (type === 'typography') {\n options['typography'] = {\n useSyntaxHighlighting: useSyntaxHighlighting(areaString)\n };\n }\n\n if (type === 'grid') {\n const _toggle_value = getGridToggleValue(areaString);\n\n options['grid'] = {\n toggle: _toggle_value,\n both: _toggle_value === 'both',\n rows: _toggle_value === 'rows',\n columns: _toggle_value === 'columns'\n };\n }\n\n if (type === 'spacing') {\n const _toggle_value = getSpacingToggleValue(areaString);\n\n options['spacing'] = {\n both: _toggle_value === 'both',\n margin: _toggle_value === 'margin',\n padding: _toggle_value === 'padding',\n bound: areaString.includes('bound')\n };\n }\n\n return { ...options, ...customOptions };\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","/* node:coverage disable */\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 */\n/* node:coverage enable */\nexport const uniqueID = (): string =>\n '_' + Math.random().toString(36).substring(2, 11);\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\n/**\n * Determines if an HTML element is hidden based on its visibility properties.\n *\n * @param {HTMLElement} element - The HTML element to check for visibility.\n * @returns {boolean} True if the element is hidden, false otherwise.\n *\n * @example\n * ```ts\n * const element = document.getElementById('my-element');\n * if (element) {\n * const hidden = isElementHidden(element);\n * console.log(hidden); // true if the element is hidden, false if visible\n * }\n * ```\n */\nexport const isElementHidden = (element: HTMLElement): boolean =>\n !element.checkVisibility({\n opacityProperty: true,\n checkVisibilityCSS: true\n } as Record<string, boolean>);\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","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 await waitForFrame();\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 await waitForFrame();\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\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.scrollY;\n const _el_offset_left = _target_rect.left + window.scrollX;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: 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","/* 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 styles = styles.reduce((acc, st) => {\n acc[st.key] = st.value;\n\n return acc;\n }, {});\n }\n\n Object.assign(el.style, styles);\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","/* node:coverage disable */\n/**\n * This feature will highlight the grid spacing in a `display: grid;` element.\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"grid [columns|rows]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'grid',\n * grid: {\n * toggle: 'both'\n * }\n * };\n *\n * grid(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DATA_ATTRIBUTE } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { offset } from '../../utils/position';\nimport { add as addStyles, get as getStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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 * @param {SpeccerOptionsInterface} options - Options to determine what to draw\n * @returns {Promise<void>}\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * const styles = window.getComputedStyle(targetElement);\n * await create(targetElement, styles);\n * }\n * ```\n */\nexport const create = async (\n targetElement: HTMLElement,\n styles: CSSStyleDeclaration,\n options: SpeccerOptionsInterface\n): Promise<void> => {\n await waitForFrame();\n\n const { grid } = options;\n\n if (!grid) return;\n\n const { toggle } = grid;\n const { height, width } = targetElement.getBoundingClientRect();\n const { top, left } = await offset(targetElement);\n const { gridTemplateColumns, gridTemplateRows, padding } = styles;\n const _pin_element_id = `speccer-${options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n if (toggle === 'columns' || toggle === 'both') {\n const columnGap = parseInt(styles.columnGap);\n const gridColumnContainer = 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) gridColumnContainer.classList.add('speccer-small-grid');\n\n gridColumnContainer.setAttribute('data-speccer-id', _pin_element_id);\n\n setClassNames(\n gridColumnContainer,\n 'ph-speccer speccer speccer-grid-container'\n );\n\n addStyles(gridColumnContainer, {\n height: `${height + 64}px`,\n width: `${width}px`,\n left: `${left}px`,\n top: `${top - 32}px`,\n padding: padding,\n gridTemplateColumns: gridTemplateColumns\n });\n\n const numberOfColumnItems = gridTemplateColumns.split(' ').length;\n\n for (let i = 0; i < numberOfColumnItems; i++) {\n const gridItem = document.createElement('div');\n\n setClassNames(gridItem, 'ph-speccer speccer speccer-grid-item');\n gridColumnContainer.appendChild(gridItem);\n }\n document.body.appendChild(gridColumnContainer);\n }\n\n if (toggle === 'rows' || toggle === 'both') {\n const rowGap = parseInt(styles.rowGap);\n const gridRowContainer = document.createElement('div');\n\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-row-gap-original',\n `${rowGap}px`\n );\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-row-gap',\n `${rowGap < 24 ? 24 : rowGap}px`\n );\n\n if (rowGap < 24) gridRowContainer.classList.add('speccer-small-grid');\n\n gridRowContainer.setAttribute('data-speccer-id', _pin_element_id);\n gridRowContainer.classList.add('ph-speccer');\n gridRowContainer.classList.add('speccer');\n gridRowContainer.classList.add('speccer-grid-row-container');\n\n setClassNames(\n gridRowContainer,\n 'ph-speccer speccer speccer-grid-row-container'\n );\n\n addStyles(gridRowContainer, {\n width: `${width + 64}px`,\n height: `${height}px`,\n top: `${top}px`,\n left: `${left - 32}px`,\n padding: padding,\n gridTemplateRows: gridTemplateRows\n });\n\n const numberOfRowItems = gridTemplateRows.split(' ').length;\n\n for (let i = 0; i < numberOfRowItems; i++) {\n const gridItem = document.createElement('div');\n\n setClassNames(gridItem, 'ph-speccer speccer speccer-grid-row-item');\n gridRowContainer.appendChild(gridItem);\n }\n document.body.appendChild(gridRowContainer);\n }\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 * \n *\n * @param {HTMLElement} targetElement - The target element to add the grid overlay to.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\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 *\n * grid(targetElement);\n * ```\n *\n * ##### Only rows\n *\n * \n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'grid',\n * grid: {\n * toggle: 'rows'\n * }\n * };\n *\n * grid(targetElement, options);\n * ```\n */\nexport const grid = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute(SPECCER_DATA_ATTRIBUTE) || '';\n const _target_style = await getStyles(targetElement);\n const _options = getOptions(_areas_string, _target_style, options);\n\n if (_options.type !== 'grid' || !_options.grid) return;\n\n await waitForFrame();\n\n await create(targetElement, _target_style, _options);\n};\n","/* node:coverage disable */\n/**\n * This feature marks given element\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"mark\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'mark'\n * };\n *\n * mark(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DATA_ATTRIBUTE } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { getRec } from '../../utils/position';\nimport { add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\n\n/**\n * Create a marker element with an optional element type.\n *\n * @param {string} id - The id.\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 = (id: string, n = 'span'): HTMLElement => {\n const _mark_element = document.createElement(n);\n\n _mark_element.setAttribute('id', id);\n\n setClassNames(_mark_element, 'ph-speccer speccer mark');\n\n return _mark_element;\n};\n\n/**\n * Create a marker element and add it to the body with styles matching a specified element.\n *\n * \n *\n * @param {HTMLElement} targetElement - 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 targetElement = document.getElementById('target');\n * mark(targetElement);\n * ```\n */\nexport const mark = async (targetElement: HTMLElement): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute(SPECCER_DATA_ATTRIBUTE) || '';\n\n await waitForFrame();\n\n const _options = getOptions(_areas_string, getComputedStyle(targetElement));\n\n if (_options.type !== 'mark') return;\n\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n const _mark_element = create(_pin_element_id);\n\n document.body.appendChild(_mark_element);\n\n const _positional_styles = await getRec(_mark_element, targetElement);\n const { left, top, height, width } = _positional_styles.absolute();\n const _mark_styles = {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n\n await addStyles(_mark_element, _mark_styles);\n};\n","/* node:coverage disable */\n/**\n * This feature measures given element\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"measure [height left|right] | [width top|bottom]\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * measure: {\n * height: true\n * }\n * };\n *\n * measure(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { MeasureAreaEnum } from '../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { cx, set as setClassNames } from '../../utils/classnames';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { getRec } from '../../utils/position';\nimport { 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 {SpeccerOptionsInterface} options - The options.\n * @param {string} id - The element id.\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 options: SpeccerOptionsInterface,\n id: string,\n tag = 'span'\n): HTMLElement => {\n const _el = document.createElement(tag);\n\n _el.setAttribute('title', `${text}px`);\n _el.setAttribute('id', id);\n _el.setAttribute('data-measure', `${parseInt(String(text), 10)}px`);\n\n const { measure, position } = options;\n const _class_names = cx('ph-speccer speccer measure', {\n height: measure?.height || false,\n width: measure?.width || false,\n slim: measure?.slim || false,\n [position]: true\n });\n\n setClassNames(_el, _class_names);\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 based on the attribute values from `data-speccer`.\n *\n * \n *\n * @param {HTMLElement} targetElement - The target element to match styles with.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<void>} - A promise that resolves after creating and styling the measurement element.\n *\n * @example\n * ##### Height to the right\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * measure: {\n * height: true\n * }\n * };\n *\n * measure(targetElement,options);\n * ```\n *\n * ##### Slim width to the bottom\n *\n * \n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'bottom',\n * measure: {\n * slim: true,\n * width: true\n * }\n * };\n *\n * measure(targetElement,options);\n * ```\n */\nexport const measure = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _options = getOptions(\n _areas_string,\n getComputedStyle(targetElement),\n options\n );\n\n if (_options.type !== 'measure' || !_options.measure) return;\n\n const { measure, position } = _options;\n\n await waitForFrame();\n\n const _target_rect = targetElement.getBoundingClientRect();\n const _width_modifier = !measure.slim ? 48 : 0;\n const _height_modifier = !measure.slim ? 96 : 0;\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n if (measure.width) {\n if (position === MeasureAreaEnum.Bottom) {\n const _measure_el = create(_target_rect.width, _options, _pin_element_id);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\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 { left, top, width, height } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height + _width_modifier}px`\n });\n }\n } else {\n const _measure_el = create(_target_rect.width, _options, _pin_element_id);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\n const { left, top, width } = _positional_styles.fromTop({\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 { left, top, width, height } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top - _width_modifier}px`,\n width: `${width}px`,\n height: `${height + _width_modifier}px`\n });\n }\n }\n } else if (measure.height) {\n if (position === MeasureAreaEnum.Right) {\n const _measure_el = create(\n _target_rect.height,\n _options,\n _pin_element_id\n );\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\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 { left, top, height, width } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width + _height_modifier}px`\n });\n }\n } else {\n const _measure_el = create(\n _target_rect.height,\n _options,\n _pin_element_id\n );\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\n const { left, top, height } = _positional_styles.fromLeft({\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 { left, top, height, width } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left - _height_modifier}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width + _height_modifier}px`\n });\n }\n }\n }\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { set as setClassNames, cx } from '../../../utils/classnames';\n\n/**\n * Create a pin element with optional content, area description, and element type.\n *\n * @param {string} content - The content to add to the element.\n * @param {SpeccerOptionsInterface} options - The option for styling.\n * @param {string} id - The id of the pinned element\n * @param {string} n - The element type.\n * @returns {HTMLElement} - The created pin element.\n *\n * @example\n * ```ts\n * const pinElement = createPinElement('A', 'outline top', 'div');\n * document.body.appendChild(pinElement);\n * ```\n */\nexport const createPinElement = (\n content = '',\n options: SpeccerOptionsInterface,\n id = '',\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _extra_class_names: Record<string, boolean> = {};\n const { position, pin = {} as Record<string, boolean> } = options;\n const {\n useSVGLine,\n useCurlyBrackets,\n text,\n parent,\n bracket,\n enclose,\n subtle\n } = pin;\n\n _extra_class_names['text'] = text;\n _extra_class_names['parent'] = parent;\n _extra_class_names['bracket'] = bracket;\n _extra_class_names['enclose'] = enclose;\n _extra_class_names['subtle'] = subtle;\n _extra_class_names['svg'] = useSVGLine;\n _extra_class_names['curly'] = useCurlyBrackets;\n _extra_class_names[position] = true;\n\n if (parent && !bracket && !useCurlyBrackets && !subtle)\n _extra_class_names.svg = true;\n\n if ((!bracket && !enclose) || (bracket && useCurlyBrackets))\n _el.innerHTML = content;\n else if (bracket || enclose) _el.setAttribute('data-pin-counter', content);\n\n const _class_names = cx('ph-speccer speccer pin', _extra_class_names);\n\n setClassNames(_el, _class_names);\n\n _el.setAttribute('id', id);\n\n return _el;\n};\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","import { SpeccerOptionsInterface } from '../../types/speccer';\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 options: SpeccerOptionsInterface;\n\n /**\n * Creates a new DrawCircle instance.\n * @param {HTMLElement} el - The element used to position the circle.\n * @param {number} radius - The radius of the circle\n * @param {SpeccerOptionsInterface} options - The options used to identify position\n */\n constructor(\n el: HTMLElement,\n radius: number,\n options: SpeccerOptionsInterface\n ) {\n this.#init(el, radius, options);\n }\n\n /**\n * Initializes the DrawCircle instance.\n * @param {HTMLElement} el - The element used to position the circle.\n * @param {number} radius - The radius of the circle\n * @param {SpeccerOptionsInterface} options - The options 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, options: SpeccerOptionsInterface) {\n if (!el || !radius || !options) {\n throw new Error('Missing inputs el or radius or options');\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.options = options;\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 const { x, y } = await intrinsic_coords(this.el, this.options.position);\n\n this.circle.setAttribute('r', this.radius + ''); // SVG attributes\n this.circle.setAttribute('cx', Math.round(x) + ''); // SVG attributes\n this.circle.setAttribute(\n 'cy',\n Math.round(y + document.documentElement.scrollTop) + ''\n ); // 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 CoordinatesForBezierObjectType,\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 {CreateCoordinatesForCurveCoordParamType} coords - The coordinates of the start and end points.\n * @param {CreateCoordinatesForCurveOptionsParamType} 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): CoordinatesForBezierObjectType => {\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 if (!direct) {\n return {\n firstPoint,\n firstControl: { x: x1 + (x2 - x1) / 2, y: y1 }, // Control point for the first point\n lastPoint,\n lastControl: { x: x1 + (x2 - x1) / 2, y: y2 }\n };\n }\n\n if (firstSet) {\n if (direction === 'west') {\n return {\n firstPoint,\n firstControl: { x: x1 - 32, y: y1 - 16 / 2 },\n lastPoint,\n lastControl: { x: x2 + 32, y: y2 }\n };\n } else if (direction === 'south') {\n return {\n firstPoint,\n firstControl: { x: x1 - 16 / 2, y: y1 + 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 - 32 }\n };\n } else if (direction === 'east') {\n return {\n firstPoint,\n firstControl: { x: x1 + 32, y: y1 - 16 / 2 },\n lastPoint,\n lastControl: { x: x2 - 32, y: y2 }\n };\n } else {\n return {\n firstPoint,\n firstControl: { x: x1 - 16 / 2, y: y1 - 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 + 32 }\n };\n }\n } else {\n if (direction === 'west') {\n return {\n firstPoint,\n firstControl: { x: x1 - 32, y: y1 + 16 / 2 },\n lastPoint,\n lastControl: { x: x2 + 32, y: y2 }\n };\n } else if (direction === 'south') {\n return {\n firstPoint,\n firstControl: { x: x1 + 16 / 2, y: y1 + 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 - 32 }\n };\n } else if (direction === 'east') {\n return {\n firstPoint,\n firstControl: { x: x1 + 32, y: y1 + 16 / 2 },\n lastPoint,\n lastControl: { x: x2 - 32, y: y2 }\n };\n } else {\n return {\n firstPoint,\n firstControl: { x: x1 + 16 / 2, y: y1 - 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 + 32 }\n };\n }\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(\n {\n x1,\n x2,\n y1: y1 + document.documentElement.scrollTop,\n y2: y2 + document.documentElement.scrollTop\n },\n { direction: '' }\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 * 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 { SpeccerOptionsInterface } from '../../types/speccer';\nimport { 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 options: SpeccerOptionsInterface;\n line: SVGPathElement;\n\n /**\n * Creates a new DrawSVGLine instance.\n * @param {HTMLElement} startElement - The starting element for the line.\n * @param {HTMLElement} stopElement - The ending element for the line.\n * @param {SpeccerOptionsInterface} [options] - The ending element for the line.\n */\n constructor(\n startElement: HTMLElement,\n stopElement: HTMLElement,\n options: SpeccerOptionsInterface = {} as SpeccerOptionsInterface\n ) {\n this.#init(startElement, stopElement, options);\n }\n\n /**\n * Initializes the DrawSVGLine instance.\n * @param {HTMLElement} startElement - The starting element for the line.\n * @param {HTMLElement} stopElement - The ending element for the line.\n * @param {SpeccerOptionsInterface} [options] - 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(\n startElement: HTMLElement,\n stopElement: HTMLElement,\n options: SpeccerOptionsInterface = {} as SpeccerOptionsInterface\n ) {\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 this.options = options;\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 const { pin } = this.options;\n\n if (pin?.text) {\n _new_path.classList.add('text');\n }\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 no-console:0 */\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\nimport { SpeccerOptionsInterface } from '../types/speccer';\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 * @param {SpeccerOptionsInterface|undefined} [options] - Options\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 options?: SpeccerOptionsInterface | undefined\n): SpacingCSSPropertiesType => {\n const {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n } = style;\n\n if (options?.spacing?.padding) {\n return {\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n };\n }\n\n if (options?.spacing?.margin) {\n return {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight\n };\n }\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 { PinAreaEnum } from '../../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { SpeccerStylesReturnType } from '../../../types/styles';\nimport { pinSpace, measureSize } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Get styles for pin elements based on the specified area and options.\n *\n * @param {HTMLElement} targetElement - The target element.\n * @param {HTMLElement} pinElement - The pin element.\n * @param {HTMLElement} parentElement - The parent element.\n * @param {SpeccerOptionsInterface} options - The 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 pinElement = document.getElementById('pin');\n * const options = { useCurlyBrackets: true };\n * const styles = await styles(area, targetElement, pinElement, parentElement, options);\n * console.log(styles);\n * ```\n */\nexport const styles = async (\n targetElement: HTMLElement,\n pinElement: HTMLElement,\n parentElement: HTMLElement,\n options: SpeccerOptionsInterface\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const { pin = {} as Record<string, boolean>, position } = options;\n const { useCurlyBrackets, subtle, bracket, text, parent, enclose } = pin;\n const SPECCER_PIN_SPACE = pinSpace(pinElement);\n const SPECCER_MEASURE_SIZE = measureSize(pinElement);\n const _positional_styles = await getRec(pinElement, targetElement);\n\n if (enclose) {\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 ((parent || text) && !bracket && !useCurlyBrackets && !subtle) {\n if (position === PinAreaEnum.Right) {\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 (position === PinAreaEnum.Bottom) {\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 (position === PinAreaEnum.Left) {\n const { top } = _positional_styles.fromLeft({\n center: true\n });\n\n await waitForFrame();\n\n const { left } = parentElement.getBoundingClientRect();\n\n return {\n // If we're pinning with text only, we need to move the element a bit further to the left\n left: `${left - SPECCER_PIN_SPACE * 1.5 - (text ? 170 : 0)}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 (position === PinAreaEnum.Left) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (position === PinAreaEnum.Right) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (position === PinAreaEnum.Bottom) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\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 { createPinElement } from './create-pin-element';\nimport { styles } from './styles';\n\n/**\n * Create and style the pin element as needed.\n *\n * This function appends a new pin element to the document body based on the `data-speccer=\"pin\"` attribute\n * of the target element. It handles different styles, such as curly brackets or lines, based on the pin type.\n *\n * @param {HTMLElement} targetElement - The target element that contains the pin data.\n * @param {HTMLElement} parentElement - The parent element\n * @param {string} content - The content to use.\n * @param {SpeccerOptionsInterface} options - options\n * @returns {Promise<string|void>} A promise that resolves to the id of the pin element when the process is completed, or `void` if required input is invalid.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * const parentElement = document.getElementById('parent');\n * const content = 0;\n * const options = { … };\n * pinElement(targetElement, parentElement, content, options).then(() => {\n * console.log('process completed');\n * });\n * ```\n */\nexport const pinElement = async (\n targetElement: HTMLElement,\n parentElement: HTMLElement,\n content: string,\n options: SpeccerOptionsInterface\n): Promise<string | void> => {\n if (!targetElement) return;\n\n if (options.type !== 'pin' || !options.pin) return;\n\n const _pin_element_id = `speccer-${options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n const _pin_element = createPinElement(content, options, _pin_element_id);\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n document.body.appendChild(_pin_element);\n\n const _pin_styles = await styles(\n targetElement as HTMLElement,\n _pin_element,\n parentElement,\n options\n );\n\n await add(_pin_element, _pin_styles);\n\n const isText =\n options.pin.text &&\n targetElement.getAttribute('data-speccer-title') !== null;\n const _should_draw_circle =\n options.pin.parent &&\n !options.pin.enclose &&\n !options.pin.bracket &&\n !isText;\n\n if (options.pin.useSVGLine) {\n new DrawSVGLine(targetElement as HTMLElement, _pin_element, options);\n\n if (_should_draw_circle) new DrawCircle(targetElement, 5, options);\n } else if (options.pin.useCurlyBrackets) {\n new DrawSVGCurlyBracket(targetElement as HTMLElement, _pin_element);\n }\n\n return _pin_element_id;\n};\n","let _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 * @param {string|string[]} literalsToUse - Literals to use\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 = (\n targetIndex: number,\n literalsToUse: string | string[]\n): string => {\n let _character_to_use = literalsToUse[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 = `${literalsToUse[_index_to_use]}${literalsToUse[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n return _character_to_use;\n};\n","/* node:coverage disable */\n/**\n * This feature annotate or highlight the anatomy of an element.\n *\n * \n *\n * In your component examples, use the following attribute. Remember to use the `data-speccer=\"pin-area\"`-attribute on a parent element to scope the marking.\n *\n * @example\n * ```html\n * <div data-speccer=\"pin-area\">\n * <div\n * data-speccer=\"pin [bracket [curly] |enclose] [left|right|top|bottom]\"\n * class=\"...\"\n * ></div>\n * </div>\n * ```\n *\n * @packageDocumentation\n */\n// eslint-disable-next-line import/no-unused-modules\n/* node:coverage enable */\nexport { createPinElement } from './utils/create-pin-element';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { pinElement } from './utils/pin-element';\n\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { SPECCER_LITERALS } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { isElementHidden } from '../../utils/node';\nimport { waitForFrame } from '../../utils/wait';\n\nimport { getCharacterToUse } from './utils/get-character-to-use';\nimport { getContentForPin } from './utils/get-content-for-pin';\nimport { pinElement } from './utils/pin-element';\n\n/**\n * Create pinned elements based on the section element and its data-speccer attributes.\n *\n * @param {HTMLElement} sectionElement - The section element containing pinned elements.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<void>} - A promise that resolves after creating pinned elements.\n *\n * @example\n * ```ts\n * const sectionElement = document.getElementById('section');\n * pinElements(sectionElement);\n * ```\n */\nexport const pinElements = async (\n sectionElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!sectionElement) return;\n\n const _els_to_be_pinned = sectionElement.querySelectorAll(\n '[data-speccer^=\"pin\"]'\n );\n\n if (!_els_to_be_pinned || _els_to_be_pinned.length === 0) return;\n\n const _literals_to_use =\n (sectionElement.getAttribute('data-speccer-literals') as string | null) ||\n window.SPECCER_LITERALS ||\n SPECCER_LITERALS;\n\n [..._els_to_be_pinned]\n .filter(\n async (targetElement: HTMLElement) => !isElementHidden(targetElement)\n )\n .forEach(\n async (\n targetElement: HTMLElement,\n targetIndex: number\n ): Promise<void> => {\n const _symbol = getCharacterToUse(targetIndex, _literals_to_use);\n const _areas_string = targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _target_style = getComputedStyle(targetElement);\n const _options = getOptions(_areas_string, _target_style, options);\n const _content = getContentForPin(_symbol, targetElement, _options);\n\n await pinElement(targetElement, sectionElement, _content, _options);\n }\n );\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\n\n/**\n * Generates the content for a pin element based on the provided symbol, target element, and options.\n *\n * @param {string} symbol - The default symbol to use if no text or description is provided.\n * @param {HTMLElement} targetElement - The HTML element for which the content is being generated.\n * @param {SpeccerOptionsInterface} options - The options that define how the content should be generated.\n * @returns {string} The generated content for the pin element.\n *\n * @example\n * ```ts\n * const symbol = '★';\n * const targetElement = document.getElementById('myElement');\n * const options = { pin: { text: true } };\n * const content = getContentForPin(symbol, targetElement, options);\n * console.log(content);\n * // Output: '<span class=\"ph-speccer title\">Title Text</span>'\n * ```\n */\nexport const getContentForPin = (\n symbol: string,\n targetElement: HTMLElement,\n options: SpeccerOptionsInterface\n): string => {\n const { pin } = options;\n\n if (!pin) return symbol;\n\n const { text } = pin;\n const _is_text =\n text && targetElement.getAttribute('data-speccer-title') !== null;\n\n if (!_is_text) return symbol;\n\n const _title = targetElement.getAttribute('data-speccer-title');\n const _description = targetElement.getAttribute('data-speccer-description');\n const _heading =\n targetElement.nodeName.indexOf('H') === 0\n ? `<span class=\"ph-speccer heading\">${targetElement.nodeName}</span>`\n : '';\n\n if (!_description && _title)\n return `${_heading}<span class=\"ph-speccer title\">${_title}</span>`;\n\n if (_description && _title)\n return `${_heading}<span class=\"ph-speccer title\">${_title}</span><span class=\"ph-speccer description\">${_description.replaceAll('\\\\n', '<br/>')}</span>`;\n\n return symbol;\n};\n","/* node:coverage disable */\n/**\n * This feature highlights the spacing of an element.\n *\n * \n * *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"spacing [padding|margin][bound]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { cx, set as setClassNames } from '../../utils/classnames';\nimport {\n getSpacing,\n getClassNameFromCSSProperty,\n getNumberValue\n} from '../../utils/css';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { get as getStyles, add as addStyles } 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}px`);\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 * \n *\n * @param {HTMLElement} targetElement - The target element to create spacing elements for.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options\n * @returns {Promise<void>} - A promise that resolves after creating and positioning the spacing elements.\n *\n * @example\n *\n * ##### Default, padding and margin\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n *\n * ##### Only padding\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * spacing: {\n * padding: true\n * }\n * };\n *\n * element(targetElement, options);\n *\n * ##### Bound style, like the old feature\n *\n * \n *\n * This option binds the speccer elements to the bounds of the element container.\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * spacing: {\n * bound: true,\n * }\n * };\n *\n * element(targetElement, options);\n * ```\n */\nexport const spacing = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n const _target_styles = await getStyles(targetElement);\n const _options = getOptions(_areas_string, _target_styles, options);\n\n if (_options.type !== 'spacing' || !_options.spacing) return;\n\n const _target_spacing_styles = getSpacing(_target_styles, _options);\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 targetElement.classList.add('is-specced');\n\n const _pin_element_id = `speccer-spacing-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n _target_pruned_spacing_styles.forEach(async (property) => {\n const _value = getNumberValue(_target_spacing_styles[property]);\n const _speccer_el = create(_value);\n\n _speccer_el.setAttribute('data-speccer-id', _pin_element_id);\n\n const _class_name = getClassNameFromCSSProperty(property);\n\n setClassNames(\n _speccer_el,\n cx(_class_name, {\n bound: _options?.spacing?.bound ? true : false\n })\n );\n document.body.appendChild(_speccer_el);\n\n const _styles = await position(property, _value, targetElement, _options);\n\n await addStyles(_speccer_el, _styles as object);\n });\n};\n","import { PositionUnitPropertiesType } from '../../../types/position';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { offset } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Set the position and dimensions of a spacing element relative to a target element.\n *\n * @param {string} property - The CSS property to set (e.g., 'marginTop', 'marginLeft', etc.).\n * @param {number} value - The value of the CSS property.\n * @param {HTMLElement} targetElement - The target element.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<PositionUnitPropertiesType|undefined>} - A promise that resolves after setting the position and dimensions.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * position('marginTop', 20, targetElement);\n * ```\n */\nexport const position = async (\n property: string,\n value: number,\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<PositionUnitPropertiesType | undefined> => {\n await waitForFrame();\n\n const _target_rect = targetElement.getBoundingClientRect();\n const _target_offset = await offset(targetElement);\n const _width_modifier = options?.spacing?.bound ? 0 : 96;\n const _height_modifier = options?.spacing?.bound ? 0 : 48;\n\n if (property === 'marginTop')\n return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top - value + 'px'\n };\n\n if (property === 'marginRight')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top + parseInt(_target_rect.height + '', 10) + 'px'\n };\n\n if (property === 'marginLeft')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top + 'px'\n };\n\n if (property === 'paddingBottom')\n return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top:\n _target_offset.top +\n (parseInt(_target_rect.height + '', 10) - value) +\n 'px'\n };\n\n if (property === 'paddingRight')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: _target_rect.height + _height_modifier + 'px',\n width: `${value}px`,\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n };\n\n return undefined;\n};\n","/* node:coverage disable */\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 */\n/* node:coverage enable */\nexport const decimal = (number: string | number, decimals = 3): string => parseFloat(String(number)).toFixed(decimals);\n","/**\n * This feature presents typography\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"typography [top|right|bottom|left] [syntax]\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * type: 'typography',\n * typography: {\n * useSyntaxHighlighting: false\n * }\n * };\n *\n * typography(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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 {SpeccerOptionsInterface} options - Options.\n * @param {string} id - The id.\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 = (\n html: string,\n options: SpeccerOptionsInterface,\n id: string\n): HTMLElement => {\n const _el = document.createElement('div');\n const { typography, position } = options;\n const _class_names = cx('ph-speccer speccer typography', {\n syntax: typography?.useSyntaxHighlighting || false,\n [position]: true\n });\n\n _el.setAttribute('id', id);\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 * \n *\n * @param {HTMLElement} targetElement - The target element to specc typography for.\n * @param {SpeccerOptionsInterface|undefined} [options] - Custom options\n * @returns {Promise<void>} - A promise that resolves once typography element is created and positioned.\n *\n * @example\n *\n * ##### Default\n *\n * ```ts\n * const targetElement = document.querySelector('.target');\n * if (targetElement) {\n * element(targetElement);\n * }\n * ```\n *\n * ##### With syntax higlight feature\n *\n * \n *\n * ```ts\n * const targetElement = document.querySelector('.target');\n * const options = {\n * typography : {\n * useSyntaxHighlighting: true\n * }\n * };\n *\n * if (targetElement) {\n * element(targetElement, options);\n * }\n * ```\n */\nexport const typography = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _options = getOptions(\n _areas_string,\n getComputedStyle(targetElement),\n options\n );\n\n if (_options.type !== 'typography' || !_options.typography) return;\n\n targetElement.classList.add('is-specced');\n\n const _html = await template(\n targetElement,\n _options.typography.useSyntaxHighlighting\n );\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n const _speccer_el = create(_html, _options, _pin_element_id);\n\n document.body.appendChild(_speccer_el);\n\n const _position = await position(_options, targetElement, _speccer_el);\n\n addStyles(_speccer_el, _position);\n};\n","import { getTypography } from '../../../utils/css';\nimport { get as getStyles } from '../../../utils/styles';\n\n/* node:coverage disable */\n/**\n * Generate a HTML string for typography styles of a target element.\n *\n * @param {HTMLElement} targetElement - 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 */\n/* node:coverage enable */\nexport const template = async (\n targetElement: HTMLElement,\n useHighlighting = false\n): Promise<string> => {\n const _target_styles = await getStyles(targetElement);\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 { TypographyAreaEnum } from '../../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\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 {SpeccerOptionsInterface} options - Options.\n * @param {HTMLElement} targetElement - The target element.\n * @param {HTMLElement} speccerElement - 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 options = {…};\n * const position = await position(options, targetElement, speccerElement);\n * console.log(position); // { left: '10px', top: '20px' }\n * ```\n */\nexport const position = async (\n options: SpeccerOptionsInterface,\n targetElement: HTMLElement,\n speccerElement: HTMLElement\n): Promise<{ left: string; top: string }> => {\n const _target_rect = targetElement.getBoundingClientRect();\n const SPECCER_PIN_SPACE = pinSpace(speccerElement);\n const _speccer_el_rect = speccerElement.getBoundingClientRect();\n const _el_offset = await offset(targetElement);\n const { typography, position } = options;\n\n if (typography && position === TypographyAreaEnum.Right) {\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(\n _el_offset.top,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n\n return {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n }\n\n if (typography && position === TypographyAreaEnum.Top) {\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\n return {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n }\n\n if (typography && position === TypographyAreaEnum.Bottom) {\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 return {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n }\n\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\n return {\n left: _left_layout_position_left,\n top: _left_layout_position_top\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","/* node:coverage disable */\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 */\n/* node:coverage enable */\nimport { grid as gridElement } from '../features/grid';\nimport { mark as markElement } from '../features/mark';\nimport { measure as measureElement } from '../features/measure';\nimport { pinElements } from '../features/pin';\nimport { spacing as spacingElement } from '../features/spacing';\nimport { typography as typographyElement } from '../features/typography';\nimport { SpeccerFunctionType } from '../types/speccer';\nimport {\n SPECCER_DATA_ATTRIBUTE,\n SPECCER_FEATURE_GRID,\n SPECCER_FEATURE_MARK,\n SPECCER_FEATURE_MEASURE,\n SPECCER_FEATURE_PIN_AREA,\n SPECCER_FEATURE_SPACING,\n SPECCER_FEATURE_TYPOGRAPHY\n} from '../utils/constants';\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 _spacing_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n spacingElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"],[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)`\n )) {\n _spacing_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(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MEASURE}\"]`\n )) {\n _measure_observer.observe(el);\n }\n\n const _mark_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n markElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MARK}\"]`\n )) {\n _mark_observer.observe(el);\n }\n\n const _typography_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n typographyElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_TYPOGRAPHY}\"]`\n )) {\n _typography_observer.observe(el);\n }\n\n const _grid_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n gridElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_GRID}\"]`\n )) {\n _grid_observer.observe(el);\n }\n\n const _pin_observer = new IntersectionObserver(async (els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n await pinElements(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}=\"${SPECCER_FEATURE_PIN_AREA}\"]`\n )) {\n _pin_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, form, main, nav, aside, [role=\"section\"], [role=\"banner\"],\n[role=\"complementary\"], [role=\"contentinfo\"], [role=\"form\"], [role=\"main\"],\n[role=\"navigation\"], [role=\"region\"], [role=\"search\"]\n`;\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} targetElement - Target HTML element.\n * @param {HTMLElement} a11yElement - 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 targetElement: HTMLElement,\n a11yElement: HTMLElement\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const SPECCER_PIN_SPACE = pinSpace(a11yElement);\n const _positional_styles = await getRec(a11yElement, targetElement);\n\n if (type === 'tabstops') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 32;\n top += 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' || type === 'autocomplete' || type === 'headings' ) {\n let { left, top } = _positional_styles.fromLeft();\n\n\n\n\n left -= SPECCER_PIN_SPACE;\n\n\n if (left <= 0) left = SPECCER_PIN_SPACE;\n\n if (top <= 0) top = SPECCER_PIN_SPACE;\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","import { add } from '../../../utils/styles';\n\nimport { createA11yElement } from './create-a11y-element';\nimport { getRole } from './get-role';\nimport { styles } from './styles';\n\n\n/**\n * Adds an accessibility element to the document body based on the target element and type.\n *\n * \n * \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 addA11yElement(targetElement, 1, 'landmark');\n * await addA11yElement(targetElement, null, 'tabstops');\n * }\n * ```\n */\nexport const addA11yElement = async (\n targetEl: HTMLElement,\n content: unknown,\n type: string\n): Promise<void> => {\n if (!targetEl || !targetEl.checkVisibility()) return;\n\n const _a11y_el = createA11yElement(type, content);\n\n if (type === 'landmark') {\n const _role = getRole(targetEl);\n const _node_name = targetEl.nodeName.toLowerCase();\n\n _a11y_el.innerHTML = `<${_node_name} role=\"${_role}\">`;\n }\n\n if (type === 'autocomplete') {\n const _autocomplete = targetEl.getAttribute('autocomplete') || '';\n\n _a11y_el.innerHTML = `autocomplete=\"${_autocomplete}\"`;\n }\n\n if (type === 'headings') {\n _a11y_el.innerHTML = targetEl.nodeName;\n _a11y_el.classList.add(targetEl.nodeName.toLowerCase());\n }\n\n if (type === 'tabstops') {\n _a11y_el.setAttribute('data-speccer-a11y-tabstops', content as string);\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","import { set as setClassNames, cx } from '../../../utils/classnames';\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 createA11yElement = (\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 autocomplete: type === 'autocomplete',\n headings: type === 'headings',\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","/* node:coverage disable */\n/**\n * Retrieves the role of a given HTML element.\n *\n * This function first checks if the `role` attribute of the target element is defined and not empty.\n * If the `role` attribute is not available, it maps certain semantic HTML elements to their respective\n * roles (e.g., `<header>` -> `'header'`). If the element does not match any predefined roles, it returns `'N/A'`.\n *\n * @param {HTMLElement} targetEl - The target HTML element whose role is to be determined.\n * @returns {string} The role of the element, or `'N/A'` if no role is applicable.\n *\n * @example\n * ```ts\n * const element = document.createElement('header');\n * const role = getRole(element);\n * console.log(role); // Output: 'header'\n *\n * const divElement = document.createElement('div');\n * divElement.setAttribute('role', 'button');\n * const divRole = getRole(divElement);\n * console.log(divRole); // Output: 'button'\n *\n * const spanElement = document.createElement('span');\n * const spanRole = getRole(spanElement);\n * console.log(spanRole); // Output: 'N/A'\n * ```\n */\n/* node:coverage enable */\nexport const getRole = (targetEl:HTMLElement): string => {\n if(!targetEl) return '';\n\n if(targetEl.role && targetEl.role !== '') return targetEl.role;\n\n const _node_name = targetEl.nodeName.toLowerCase();\n\n if(['header', 'footer', 'section', 'form', 'main', 'nav', 'aside'].includes(_node_name)) return _node_name;\n\n return 'N/A';\n};\n","import { cx, set as setClassNames } from '../../../utils/classnames';\nimport { add } from '../../../utils/styles';\nimport { SPECCER_MODIFIER_KEYS, SPECCER_PHYSICAL_KEYS } from '../constants';\n\nimport { styles } from './styles';\n\n/**\n * Adds a shortcut element to the document body based on the provided HTML element and shortcut string.\n *\n * \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 addShortcutElement(shortcutElement, 'Ctrl + Shift + A');\n * }\n * ```\n */\nexport const addShortcutElement = 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 const _shortcut_holder_class_names = cx(\n 'ph-speccer speccer a11y shortcut-holder'\n );\n\n setClassNames(_shortcut_holder, _shortcut_holder_class_names);\n\n for (const key of _keys) {\n const _key_element = document.createElement('kbd');\n const _key_text_node = document.createTextNode(key);\n const _key_element_class_names = cx('ph-speccer speccer a11y shortcut', {\n modifier: SPECCER_MODIFIER_KEYS.includes(key.toLowerCase()),\n physical: SPECCER_PHYSICAL_KEYS.includes(key.toLowerCase())\n });\n\n setClassNames(_key_element, _key_element_class_names);\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 * Remove a speccer element by removing associated elements and SVG paths.\n *\n * This function removes any speccer elements linked to the specified element and\n * also removes any SVG paths that might be associated with it.\n *\n * @param {HTMLElement} el - The HTML element to unpin.\n * @returns {void} This function does not return a value.\n *\n * @example\n * ```ts\n * const element = document.getElementById('my-element');\n * if (element) {\n * removeSpeccerElement(element);\n * }\n * ```\n */\nexport const removeSpeccerElement = (el: HTMLElement): void => {\n const _selector = el.getAttribute('data-speccer-element-id');\n\n if (!_selector) return;\n\n const _pin_element =\n document.getElementById(_selector) ||\n document.querySelectorAll(`[data-speccer-id=\"${_selector}\"]`);\n\n if (!_pin_element) return;\n\n if (Object.prototype.isPrototypeOf.call(NodeList.prototype, _pin_element)) {\n [...(_pin_element as unknown as HTMLElement[])].forEach(\n (el: HTMLElement) => {\n el.remove();\n el.classList.remove('is-specced');\n }\n );\n } else {\n // We also need to remove the svg paths if it is in use\n if (\n (_pin_element as HTMLElement).classList.contains('curly') ||\n (_pin_element as HTMLElement).classList.contains('svg')\n ) {\n const _el_ID = el.getAttribute('id');\n\n document\n .querySelectorAll(`#ph-speccer-svg path[data-start-el=\"${_el_ID}\"]`)\n .forEach((el) => el.remove());\n }\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 { a11y as initA11y } from './features/a11y';\nimport { create as gridCreate, grid as gridElement } from './features/grid';\nimport { create as markCreate, mark as markElement } from './features/mark';\nimport {\n create as measureCreate,\n measure as measureElement\n} from './features/measure';\nimport { createPinElement, pinElement, pinElements } from './features/pin';\nimport {\n create as spacingCreate,\n spacing as spacingElement\n} from './features/spacing';\nimport {\n create as typographyCreate,\n typography as typographyElement\n} from './features/typography';\nimport {\n SPECCER_DATA_ATTRIBUTE,\n SPECCER_FEATURE_GRID,\n SPECCER_FEATURE_MARK,\n SPECCER_FEATURE_MEASURE,\n SPECCER_FEATURE_PIN_AREA,\n SPECCER_FEATURE_SPACING,\n SPECCER_FEATURE_TYPOGRAPHY\n} from './utils/constants';\nimport { removeAll } from './utils/node';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { removeSpeccerElement } from './utils/remove-speccer-element';\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 pin = {\n createPinElement,\n pinElement,\n pinElements\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 spacingElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"]`\n );\n const measureElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MEASURE}\"]`\n );\n const typographyElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_TYPOGRAPHY}\"]`\n );\n const pinSectionElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}=\"${SPECCER_FEATURE_PIN_AREA}\"]`\n );\n const markElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MARK}\"]`\n );\n const gridElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_GRID}\"]`\n );\n\n for (const el of markElements) {\n markElement(el as HTMLElement);\n }\n for (const el of gridElements) {\n gridElement(el as HTMLElement);\n }\n for (const el of spacingElements) {\n spacingElement(el as HTMLElement);\n\n if (el.hasChildNodes()) {\n const _child_spacing_elements = el.querySelectorAll(\n '*:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody):not([data-speccer])'\n );\n const _areas_string: string = el.getAttribute('data-speccer') || '';\n\n if (_child_spacing_elements && _child_spacing_elements.length) {\n for (const childEl of _child_spacing_elements) {\n childEl.setAttribute('data-speccer', _areas_string);\n spacingElement(childEl as HTMLElement);\n }\n }\n }\n }\n for (const el of measureElements) {\n measureElement(el as HTMLElement);\n }\n for (const el of typographyElements) {\n typographyElement(el as HTMLElement);\n }\n for (const el of pinSectionElements) {\n pinElements(el as HTMLElement);\n }\n initA11y();\n};\n\nexport default speccer;\n\nactivate(speccer);\n","/**\n * This feature will annotate or highlight accessibility areas like landmarks and region. It can also display tab stops/sequence and any keyboard shortcuts assigned\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"a11y [shortcuts|tabstops|landmark|headings|autocomplete]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * a11y(targetElement);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint-disable import/no-unused-modules */\nimport { isElementHidden } from '../../utils/node';\n\nimport {\n SPECCER_LANDMARK_ELEMENTS_SELECTOR,\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n} from './constants';\nimport { addA11yElement } from './utils/add-a11y-element';\nimport { addShortcutElement } from './utils/add-shortcut-element';\n\n/**\n * Initializes the accessibility elements on the document.\n *\n * @example\n * ```ts\n * a11y();\n * ```\n */\nexport const a11y = () => {\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 const _autocomplete_elements = document.querySelectorAll(\n '[data-speccer*=\"a11y autocomplete\"]'\n );\n const _headings_elements = document.querySelectorAll(\n '[data-speccer*=\"a11y headings\"]'\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 (\n !_shortcut_string ||\n _shortcut_string === '' ||\n isElementHidden(el as HTMLElement)\n )\n continue;\n\n addShortcutElement(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(SPECCER_TABBABLE_ELEMENTS_SELECTOR);\n\n for (const [tabstopsIndex, tabstopsEl] of _tabstops_els.entries()) {\n if (!isElementHidden(tabstopsEl as HTMLElement)) {\n addA11yElement(tabstopsEl as HTMLElement, tabstopsIndex + 1, 'tabstops');\n continue;\n }\n\n const id = tabstopsEl.getAttribute('id');\n\n if (!id) continue;\n\n const potentialLabelElement = document.querySelector(`[for=\"${id}\"]`);\n\n if (!potentialLabelElement || isElementHidden(potentialLabelElement as HTMLElement)) continue;\n\n // This could be a fake element, like a toggle checkbox, so we use the labelElement\n addA11yElement(potentialLabelElement as HTMLElement, tabstopsIndex + 1, 'tabstops');\n }\n }\n }\n\n if (_autocomplete_elements.length) {\n for (const el of _autocomplete_elements) {\n const _autocomplete_els = el.querySelectorAll(\n '[autocomplete]'\n );\n\n for (const _autocomplete_el of _autocomplete_els) {\n if (isElementHidden(_autocomplete_el as HTMLElement)) continue;\n\n addA11yElement(_autocomplete_el as HTMLElement, null, 'autocomplete');\n }\n }\n }\n\n if (_headings_elements.length) {\n for (const el of _headings_elements) {\n const _headings_els = el.querySelectorAll(\n 'h1,h2,h3,h4,h5,h6, [role=\"heading\"]'\n );\n\n for (const _headings_el of _headings_els) {\n if (isElementHidden(_headings_el as HTMLElement)) continue;\n\n addA11yElement(_headings_el as HTMLElement, null, 'headings');\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 if (isElementHidden(landmarkEl as HTMLElement)) continue;\n\n addA11yElement(landmarkEl as HTMLElement, landmarkIndex + 1, 'landmark');\n addA11yElement(landmarkEl as HTMLElement, null, 'region');\n }\n }\n }\n};\n"],"names":["isString","variable","isNotString","isNumber","isNotNumber","isUndefined","set","el","cls","avoid","length","preparedClassNames","trim","split","filter","cl","map","classList","add","cx","cls_obj","Object","keys","classname","join","SPECCER_LITERALS","SPECCER_DATA_ATTRIBUTE","SPECCER_FEATURE_SPACING","SPECCER_FEATURE_MEASURE","SPECCER_FEATURE_TYPOGRAPHY","SPECCER_FEATURE_MARK","SPECCER_FEATURE_GRID","SPECCER_FEATURE_PIN_AREA","SpeccerAreaEnum","PinAreaEnum","MeasureAreaEnum","TypographyAreaEnum","SpacingAreaEnum","MarkAreaEnum","GridAreaEnum","getAreasFromString","areaString","isBracketArea","includes","Bracket","isEncloseArea","Enclose","isSubtle","Subtle","isParentArea","Parent","isTextArea","Text","isHeightArea","Height","isSlimArea","Slim","isWidthArea","Width","useSVG","areas","SVG","isCurly","Curly","useSyntaxHighlighting","Syntax","getFeatureBasedOnArea","targetStyle","Pin","isValidPinElement","styles","Grid","display","isValidGridElement","Mark","isValidMarkElement","Measure","isValidMeasureElement","Spacing","isValidSpacingElement","Typography","isValidTypographyElement","getPositionBasedOnArea","Left","isLeftArea","Right","isRightArea","Bottom","isBottomArea","getOptions","customOptions","type","options","slug","str","normalize","replace","toLowerCase","ltr","idx","toUpperCase","position","bracket","enclose","subtle","parent","text","useSVGLine","useCurlyBrackets","slim","height","width","_toggle_value","getGridToggleValue","toggle","both","rows","columns","getSpacingToggleValue","margin","padding","bound","uniqueID","Math","random","toString","substring","isElementHidden","element","checkVisibility","opacityProperty","checkVisibilityCSS","waitForFrame","Promise","requestAnimationFrame","hasStylePropertySet","async","property","value","getComputedStyle","getParentWithStylePropertySet","parentElement","get_horizontal_center_of_els","modifier","startRect","targetRect","get_vertical_center_of_els","offset","targetEl","_target_rect","getBoundingClientRect","_el_offset_top","top","window","scrollY","_el_offset_left","left","scrollX","stickyParentElement","getParentThatIsSticky","isSticky","originalPosition","style","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","center","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","Array","isArray","constructor","reduce","acc","st","key","assign","get","create","targetElement","grid","gridTemplateColumns","gridTemplateRows","_pin_element_id","getAttribute","setAttribute","columnGap","parseInt","gridColumnContainer","document","createElement","documentElement","setProperty","setClassNames","addStyles","numberOfColumnItems","i","gridItem","appendChild","body","rowGap","gridRowContainer","numberOfRowItems","_areas_string","_target_style","getStyles","_options","id","n","_mark_element","mark","_positional_styles","_mark_styles","tag","_el","String","measure","_class_names","_width_modifier","_height_modifier","_measure_el","createPinElement","content","_extra_class_names","pin","svg","innerHTML","coords","rect","xy","x","y","right","bottom","intrinsic_coords","pos","Error","_allowed_positions","_el_rect","DrawCircle","canvas","circle","radius","this","init","contains","getElementById","html","max","scrollHeight","offsetHeight","clientHeight","addStyle","draw","_circle_el_id","createElementNS","_el_ID","round","scrollTop","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","direct","firstSet","direction","firstPoint","lastPoint","firstControl","lastControl","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","direction_of_element","start","stop","crude","_angle","cy","ex","ey","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","getNumberValue","pinSpace","getPropertyValue","pinElement","SPECCER_PIN_SPACE","SPECCER_MEASURE_SIZE","_pin_element","_pin_styles","isText","_should_draw_circle","_index_to_use","pinElements","sectionElement","_els_to_be_pinned","querySelectorAll","_literals_to_use","forEach","targetIndex","_symbol","literalsToUse","_character_to_use","getCharacterToUse","_content","symbol","_title","_description","_heading","nodeName","indexOf","replaceAll","getContentForPin","_text_content","createTextNode","spacing","_target_styles","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","getSpacing","_target_pruned_spacing_styles","_value","_speccer_el","_class_name","getClassNameFromCSSProperty","_styles","decimal","number","decimals","parseFloat","toFixed","typography","syntax","_html","useHighlighting","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","getTypography","_fontFamily","font","_fontSize","_letterSpacing","_lineHeight","template","_position","speccerElement","_speccer_el_rect","_el_offset","Top","activate","speccer","speccerEventFunc","func","wait","immediate","timeout","context","args","callNow","clearTimeout","setTimeout","apply","debounce","removeEventListener","addEventListener","dom","readyState","lazy","_spacing_observer","IntersectionObserver","els","observer","intersectionRatio","spacingElement","target","unobserve","observe","_measure_observer","measureElement","_mark_observer","markElement","_typography_observer","typographyElement","_grid_observer","gridElement","_pin_observer","manual","_script","currentScript","_speccer_script_src","hasAttribute","resizeActivate","SPECCER_MODIFIER_KEYS","SPECCER_PHYSICAL_KEYS","a11yElement","addA11yElement","_a11y_el","tabstops","landmark","autocomplete","headings","region","_text_node","createA11yElement","_role","role","_node_name","getRole","_autocomplete","_a11y_styles","addShortcutElement","shortcutString","_keys","_shortcut_holder","_shortcut_holder_class_names","_key_element","_key_text_node","_key_element_class_names","physical","_shortcut_holder_styles","removeSpeccerElement","_selector","prototype","isPrototypeOf","call","NodeList","gridCreate","spacingCreate","measureCreate","markCreate","typographyCreate","modes","selector","e","removeAll","spacingElements","measureElements","typographyElements","pinSectionElements","markElements","gridElements","hasChildNodes","_child_spacing_elements","childEl","_tab_order_elements","_landmark_elements","_shortcut_elements","_autocomplete_elements","_headings_elements","_shortcut_string","_tabstops_els","tabstopsIndex","tabstopsEl","entries","potentialLabelElement","querySelector","_autocomplete_els","_autocomplete_el","_headings_els","_headings_el","_landmark_els","landmarkIndex","landmarkEl","initA11y"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"speccer.esm.js","sources":["../src/utils/typeof/index.ts","../src/utils/classnames.ts","../src/utils/constants.ts","../src/types/enums/area.ts","../src/utils/area.ts","../src/utils/get-options.ts","../src/utils/camel-case.ts","../src/utils/id.ts","../src/utils/node.ts","../src/utils/wait.ts","../src/utils/style-property.ts","../src/utils/position.ts","../src/utils/styles.ts","../src/features/grid/index.ts","../src/features/mark/index.ts","../src/features/measure/index.ts","../src/features/pin/utils/create-pin-element.ts","../src/utils/coords.ts","../src/utils/xy.ts","../src/utils/intrinsic-coords.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/css.ts","../src/features/pin/utils/styles.ts","../src/features/pin/utils/pin-element.ts","../src/features/pin/utils/get-character-to-use.ts","../src/features/pin/index.ts","../src/features/pin/utils/get-content-for-pin.ts","../src/features/spacing/index.ts","../src/features/spacing/utils/position.ts","../src/utils/number.ts","../src/features/typography/index.ts","../src/features/typography/utils/template.ts","../src/features/typography/utils/position.ts","../src/utils/resize.ts","../src/utils/debounce.ts","../src/config/browser.ts","../src/features/a11y/constants/index.ts","../src/features/a11y/utils/styles.ts","../src/features/a11y/utils/add-a11y-element.ts","../src/features/a11y/utils/create-a11y-element.ts","../src/features/a11y/utils/get-role.ts","../src/features/a11y/utils/add-shortcut-element.ts","../src/utils/remove-speccer-element.ts","../src/main.ts","../src/features/a11y/index.ts"],"sourcesContent":["/* 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'): void => {\n if (!el) return;\n\n if (!cls || (cls && !cls.length)) return;\n\n const preparedClassNames = cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .map((cl) => cl.trim());\n\n el.classList.add(...preparedClassNames);\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 const preparedClassNames = cls\n .trim()\n .split(' ')\n .filter((cl) => cl !== avoid)\n .filter((cl) => cl !== '')\n .map((cl) => cl.trim());\n\n el.classList.remove(...preparedClassNames);\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","/* 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\n/**\n * The name of the attribute speccer uses to identify elements to spec\n * @type {string}\n */\nexport const SPECCER_DATA_ATTRIBUTE = 'data-speccer';\n\n/**\n * The selector for the `spacing` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_SPACING = 'spacing';\n\n/**\n * The selector for the `measure` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_MEASURE = 'measure';\n\n/**\n * The selector for the `typography` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_TYPOGRAPHY = 'typography';\n\n/**\n * The selector for the `mark` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_MARK = 'mark';\n\n/**\n * The selector for the `grid` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_GRID = 'grid';\n\n/**\n * The selector for the container of the `pin` feature\n * @type {string}\n */\nexport const SPECCER_FEATURE_PIN_AREA = 'pin-area';\n","/* eslint-disable no-unused-vars */\n\n/**\n * Enum representing different areas in Speccer.\n */\nexport enum SpeccerAreaEnum {\n Empty = '', // Represents an empty area\n Left = 'left', // Represents the left area\n Right = 'right', // Represents the right area\n Bottom = 'bottom', // Represents the bottom area\n Top = 'top' // Represents the top area\n}\n\n/**\n * Enum representing different areas for the pin feature.\n */\nexport enum PinAreaEnum {\n Pin = 'pin', // Represents an pin area\n Parent = 'parent', // Represents a parent area\n Text = 'text', // Represents a text area\n Enclose = 'enclose', // Represents an enclose area\n Subtle = 'subtle', // Represents an subtle area\n Bracket = 'bracket', // Represents a bracket 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 Measure = 'measure', // Represents the measure area\n Slim = 'slim', // Represents the slim measurement area\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\n/**\n * Enum representing different typography areas.\n */\nexport enum TypographyAreaEnum {\n Typography = 'typography', // Represents the typography area\n Syntax = 'syntax', // Represents the syntax area\n Left = 'left', // Represents the left typography area\n Right = 'right', // Represents the right typography area\n Bottom = 'bottom', // Represents the bottom typography area\n Top = 'top' // Represents the top typography area\n}\n\n/**\n * Enum representing different spacing areas.\n */\nexport enum SpacingAreaEnum {\n Spacing = 'spacing' // Represents the spacing area\n}\n\n/**\n * Enum representing different mark areas.\n */\nexport enum MarkAreaEnum {\n Mark = 'mark' // Represents the mark area\n}\n\n/**\n * Enum representing different grid areas.\n */\nexport enum GridAreaEnum {\n Grid = 'grid' // Represents the grid area\n}\n","import {\n PinAreaEnum,\n MeasureAreaEnum,\n TypographyAreaEnum,\n SpacingAreaEnum,\n MarkAreaEnum,\n GridAreaEnum\n} from '../types/enums/area';\n\n/**\n * Splits a string containing areas into an array of strings.\n *\n * @param {string} 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 {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'left' is present, otherwise `false`.\n */\nexport const isLeftArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Left);\n};\n\n/**\n * Checks if 'right' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'right' is present, otherwise `false`.\n */\nexport const isRightArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Right);\n};\n\n/**\n * Checks if 'top' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'top' is present, otherwise `false`.\n */\nexport const isTopArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Top);\n};\n\n/**\n * Checks if 'bottom' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'bottom' is present, otherwise `false`.\n */\nexport const isBottomArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Bottom);\n};\n\n/**\n * Checks if 'bracket' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'bracket' is present, otherwise `false`.\n */\nexport const isBracketArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Bracket);\n};\n\n/**\n * Checks if 'enclose' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'enclose' is present, otherwise `false`.\n */\nexport const isEncloseArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Enclose);\n};\n\n/**\n * Checks if 'subtle' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'subtle' is present, otherwise `false`.\n */\nexport const isSubtle = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Subtle);\n};\n\n/**\n * Checks if 'parent' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'parent' is present, otherwise `false`.\n */\nexport const isParentArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Parent);\n};\n\n/**\n * Checks if 'text' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'text' is present, otherwise `false`.\n */\nexport const isTextArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(PinAreaEnum.Text);\n};\n\n/**\n * Checks if 'height' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'height' is present, otherwise `false`.\n */\nexport const isHeightArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Height);\n};\n\n/**\n * Checks if 'slim' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'slim' is present, otherwise `false`.\n */\nexport const isSlimArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return areas.includes(MeasureAreaEnum.Slim);\n};\n\n/**\n * Checks if 'width' area is present in the provided areaString.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'width' is present, otherwise `false`.\n */\nexport const isWidthArea = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\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 {string|null} areaString - The string containing areas.\n * @returns boolean `true` if any SVG-related area is present, otherwise `false`.\n */\nexport const useSVG = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return (\n ((isParentArea(areaString) &&\n !isEncloseArea(areaString) &&\n !isBracketArea(areaString)) ||\n isTextArea(areaString) ||\n areas.includes(PinAreaEnum.SVG)) &&\n !isCurly(areaString)\n );\n};\n\n/**\n * Checks if the provided areaString contains 'curly' and 'bracket' areas.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if both 'curly' and 'bracket' are present, otherwise `false`.\n */\nexport const isCurly = (areaString: string | null): boolean => {\n if (areaString === null) return false;\n\n const areas = getAreasFromString(areaString);\n\n return (\n areas.includes(PinAreaEnum.Curly) && areas.includes(PinAreaEnum.Bracket)\n );\n};\n\n/**\n * Checks if the provided areaString contains 'typography'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'typography' are present, otherwise `false`.\n */\nexport const isValidTypographyElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(TypographyAreaEnum.Typography);\n\n/**\n * Checks if the provided areaString contains 'spacing'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'spacing' are present, otherwise `false`.\n */\nexport const isValidSpacingElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(SpacingAreaEnum.Spacing);\n\n/**\n * Checks if the provided areaString contains 'measure'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'measure' are present, otherwise `false`.\n */\nexport const isValidMeasureElement = (areaString: string | null): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(MeasureAreaEnum.Measure);\n\n/**\n * Checks if the provided areaString contains 'pin'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'pin' are present, otherwise `false`.\n */\nexport const isValidPinElement = (areaString: string | null): boolean =>\n areaString !== null && areaString.split(' ').includes(PinAreaEnum.Pin);\n\n/**\n * Checks if the provided areaString contains 'mark'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if 'mark' are present, otherwise `false`.\n */\nexport const isValidMarkElement = (areaString: string | null): boolean =>\n areaString !== null && areaString.split(' ').includes(MarkAreaEnum.Mark);\n\n/**\n * Checks if the provided areaString contains 'grid'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @param {CSSStyleDeclaration} areaString - The string containing areas.\n * @returns boolean `true` if 'grid' are present, otherwise `false`.\n */\nexport const isValidGridElement = (\n areaString: string | null,\n styles: CSSStyleDeclaration\n): boolean =>\n areaString !== null &&\n areaString.split(' ').includes(GridAreaEnum.Grid) &&\n (styles.display === 'grid' || styles.display.includes('grid'));\n\n/**\n * Checks if the provided areaString contains 'syntax'.\n *\n * @param {string|null} areaString - The string containing areas.\n * @returns boolean `true` if both 'syntax' are present, otherwise `false`.\n */\nexport const useSyntaxHighlighting = (areaString: string | null): boolean => {\n if (areaString)\n return areaString.split(' ').includes(TypographyAreaEnum.Syntax);\n\n return false;\n};\n","import {\n SpeccerFeatureType,\n SpeccerOptionsInterface,\n SpeccerPositionType\n} from '../types/speccer';\n\nimport {\n isBottomArea,\n isBracketArea,\n isCurly,\n isEncloseArea,\n isHeightArea,\n isLeftArea,\n isParentArea,\n isRightArea,\n isSlimArea,\n isSubtle,\n isTextArea,\n isValidGridElement,\n isValidMarkElement,\n isValidMeasureElement,\n isValidPinElement,\n isValidSpacingElement,\n isValidTypographyElement,\n isWidthArea,\n useSVG,\n useSyntaxHighlighting\n} from './area';\nimport { camelCase } from './camel-case';\n\n/**\n * Determines the Speccer feature type based on the given area string and target element.\n *\n * @param {string} areaString - The string representing different area types.\n * @param {CSSStyleDeclaration} targetStyle - The target HTML element being evaluated.\n * @returns {SpeccerFeatureType} The determined Speccer feature type.\n *\n * @example\n * ```ts\n * const feature = getFeatureBasedOnArea('left right pin', document.getElementById('myElement'));\n * console.log(feature); // Output: 'pin'\n * ```\n */\nconst getFeatureBasedOnArea = (\n areaString: string,\n targetStyle: CSSStyleDeclaration\n): SpeccerFeatureType => {\n if (isValidPinElement(areaString)) return 'pin';\n\n if (isValidGridElement(areaString, targetStyle)) return 'grid';\n\n if (isValidMarkElement(areaString)) return 'mark';\n\n if (isValidMeasureElement(areaString)) return 'measure';\n\n if (isValidSpacingElement(areaString)) return 'spacing';\n\n if (isValidTypographyElement(areaString)) return 'typography';\n\n return 'pin';\n};\nconst getPositionBasedOnArea = (areaString: string): SpeccerPositionType => {\n if (isLeftArea(areaString)) return 'left';\n\n if (isRightArea(areaString)) return 'right';\n\n if (isBottomArea(areaString)) return 'bottom';\n\n return 'top';\n};\nconst getGridToggleValue = (areaString: string) => {\n if (areaString?.includes('columns')) return 'columns';\n\n if (areaString?.includes('rows')) return 'rows';\n\n return 'both';\n};\nconst getSpacingToggleValue = (areaString: string) => {\n if (areaString?.includes('margin')) return 'margin';\n\n if (areaString?.includes('padding')) return 'padding';\n\n return 'both';\n};\n\n/**\n * Generates Speccer options based on the target element and the specified area string.\n *\n * @param {HTMLElement} targetElement - The HTML element for which options are being generated.\n * @param {string} areaString - The string representing different area types.\n * @param {SpeccerOptionsInterface|undefined} [customOptions] - Custom options\n * @returns {SpeccerOptionsInterface} The generated Speccer options.\n *\n * @example\n * ```ts\n * const options = getOptions(document.getElementById('myElement'), 'left right pin');\n * console.log(options);\n * // Output: { position: { left: true, right: true, top: false, bottom: false }, type: 'pin', pin: { bracket: false, enclose: false, subtle: false, parent: false, text: false, useSVGLine: false, useCurlyBrackets: false } }\n * ```\n */\nexport const getOptions = (\n areaString: string,\n targetStyle: CSSStyleDeclaration,\n customOptions?: SpeccerOptionsInterface | undefined\n): SpeccerOptionsInterface => {\n const type = getFeatureBasedOnArea(areaString, targetStyle);\n const options: SpeccerOptionsInterface = {\n slug: camelCase(areaString),\n position: getPositionBasedOnArea(areaString),\n type\n };\n\n if (type === 'pin') {\n options['pin'] = {\n bracket: isBracketArea(areaString),\n enclose: isEncloseArea(areaString),\n subtle: isSubtle(areaString),\n parent: isParentArea(areaString),\n text: isTextArea(areaString),\n useSVGLine: useSVG(areaString),\n useCurlyBrackets: isCurly(areaString)\n };\n }\n\n if (type === 'measure') {\n options['measure'] = {\n slim: isSlimArea(areaString),\n height: isHeightArea(areaString),\n width: isWidthArea(areaString)\n };\n }\n\n if (type === 'typography') {\n options['typography'] = {\n useSyntaxHighlighting: useSyntaxHighlighting(areaString)\n };\n }\n\n if (type === 'grid') {\n const _toggle_value = getGridToggleValue(areaString);\n\n options['grid'] = {\n toggle: _toggle_value,\n both: _toggle_value === 'both',\n rows: _toggle_value === 'rows',\n columns: _toggle_value === 'columns'\n };\n }\n\n if (type === 'spacing') {\n const _toggle_value = getSpacingToggleValue(areaString);\n\n options['spacing'] = {\n both: _toggle_value === 'both',\n margin: _toggle_value === 'margin',\n padding: _toggle_value === 'padding',\n bound: areaString.includes('bound')\n };\n }\n\n return { ...options, ...customOptions };\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","/* node:coverage disable */\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 */\n/* node:coverage enable */\nexport const uniqueID = (): string =>\n '_' + Math.random().toString(36).substring(2, 11);\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\n/**\n * Determines if an HTML element is hidden based on its visibility properties.\n *\n * @param {HTMLElement} element - The HTML element to check for visibility.\n * @returns {boolean} True if the element is hidden, false otherwise.\n *\n * @example\n * ```ts\n * const element = document.getElementById('my-element');\n * if (element) {\n * const hidden = isElementHidden(element);\n * console.log(hidden); // true if the element is hidden, false if visible\n * }\n * ```\n */\nexport const isElementHidden = (element: HTMLElement): boolean =>\n !element.checkVisibility({\n opacityProperty: true,\n checkVisibilityCSS: true\n } as Record<string, boolean>);\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","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 await waitForFrame();\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 await waitForFrame();\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\n await waitForFrame();\n\n const _target_rect = targetEl.getBoundingClientRect();\n const _el_offset_top = _target_rect.top + window.scrollY;\n const _el_offset_left = _target_rect.left + window.scrollX;\n\n return {\n height: _target_rect.height,\n width: _target_rect.width,\n top: 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","/* 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 styles = styles.reduce((acc, st) => {\n acc[st.key] = st.value;\n\n return acc;\n }, {});\n }\n\n Object.assign(el.style, styles);\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","/* node:coverage disable */\n/**\n * This feature will highlight the grid spacing in a `display: grid;` element.\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"grid [columns|rows]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'grid',\n * grid: {\n * toggle: 'both'\n * }\n * };\n *\n * grid(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DATA_ATTRIBUTE } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { offset } from '../../utils/position';\nimport { add as addStyles, get as getStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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 * @param {SpeccerOptionsInterface} options - Options to determine what to draw\n * @returns {Promise<void>}\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * if (targetElement) {\n * const styles = window.getComputedStyle(targetElement);\n * await create(targetElement, styles);\n * }\n * ```\n */\nexport const create = async (\n targetElement: HTMLElement,\n styles: CSSStyleDeclaration,\n options: SpeccerOptionsInterface\n): Promise<void> => {\n await waitForFrame();\n\n const { grid } = options;\n\n if (!grid) return;\n\n const { toggle } = grid;\n const { height, width } = targetElement.getBoundingClientRect();\n const { top, left } = await offset(targetElement);\n const { gridTemplateColumns, gridTemplateRows, padding } = styles;\n const _pin_element_id = `speccer-${options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n if (toggle === 'columns' || toggle === 'both') {\n const columnGap = parseInt(styles.columnGap);\n const gridColumnContainer = 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) gridColumnContainer.classList.add('speccer-small-grid');\n\n gridColumnContainer.setAttribute('data-speccer-id', _pin_element_id);\n\n setClassNames(\n gridColumnContainer,\n 'ph-speccer speccer speccer-grid-container'\n );\n\n addStyles(gridColumnContainer, {\n height: `${height + 64}px`,\n width: `${width}px`,\n left: `${left}px`,\n top: `${top - 32}px`,\n padding: padding,\n gridTemplateColumns: gridTemplateColumns\n });\n\n const numberOfColumnItems = gridTemplateColumns.split(' ').length;\n\n for (let i = 0; i < numberOfColumnItems; i++) {\n const gridItem = document.createElement('div');\n\n setClassNames(gridItem, 'ph-speccer speccer speccer-grid-item');\n gridColumnContainer.appendChild(gridItem);\n }\n document.body.appendChild(gridColumnContainer);\n }\n\n if (toggle === 'rows' || toggle === 'both') {\n const rowGap = parseInt(styles.rowGap);\n const gridRowContainer = document.createElement('div');\n\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-row-gap-original',\n `${rowGap}px`\n );\n document.documentElement.style.setProperty(\n '--ph-speccer-grid-row-gap',\n `${rowGap < 24 ? 24 : rowGap}px`\n );\n\n if (rowGap < 24) gridRowContainer.classList.add('speccer-small-grid');\n\n gridRowContainer.setAttribute('data-speccer-id', _pin_element_id);\n gridRowContainer.classList.add('ph-speccer');\n gridRowContainer.classList.add('speccer');\n gridRowContainer.classList.add('speccer-grid-row-container');\n\n setClassNames(\n gridRowContainer,\n 'ph-speccer speccer speccer-grid-row-container'\n );\n\n addStyles(gridRowContainer, {\n width: `${width + 64}px`,\n height: `${height}px`,\n top: `${top}px`,\n left: `${left - 32}px`,\n padding: padding,\n gridTemplateRows: gridTemplateRows\n });\n\n const numberOfRowItems = gridTemplateRows.split(' ').length;\n\n for (let i = 0; i < numberOfRowItems; i++) {\n const gridItem = document.createElement('div');\n\n setClassNames(gridItem, 'ph-speccer speccer speccer-grid-row-item');\n gridRowContainer.appendChild(gridItem);\n }\n document.body.appendChild(gridRowContainer);\n }\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 * \n *\n * @param {HTMLElement} targetElement - The target element to add the grid overlay to.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\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 *\n * grid(targetElement);\n * ```\n *\n * ##### Only rows\n *\n * \n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'grid',\n * grid: {\n * toggle: 'rows'\n * }\n * };\n *\n * grid(targetElement, options);\n * ```\n */\nexport const grid = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute(SPECCER_DATA_ATTRIBUTE) || '';\n const _target_style = await getStyles(targetElement);\n const _options = getOptions(_areas_string, _target_style, options);\n\n if (_options.type !== 'grid' || !_options.grid) return;\n\n await waitForFrame();\n\n await create(targetElement, _target_style, _options);\n};\n","/* node:coverage disable */\n/**\n * This feature marks given element\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"mark\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * type: 'mark'\n * };\n *\n * mark(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { set as setClassNames } from '../../utils/classnames';\nimport { SPECCER_DATA_ATTRIBUTE } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { getRec } from '../../utils/position';\nimport { add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\n\n/**\n * Create a marker element with an optional element type.\n *\n * @param {string} id - The id.\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 = (id: string, n = 'span'): HTMLElement => {\n const _mark_element = document.createElement(n);\n\n _mark_element.setAttribute('id', id);\n\n setClassNames(_mark_element, 'ph-speccer speccer mark');\n\n return _mark_element;\n};\n\n/**\n * Create a marker element and add it to the body with styles matching a specified element.\n *\n * \n *\n * @param {HTMLElement} targetElement - 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 targetElement = document.getElementById('target');\n * mark(targetElement);\n * ```\n */\nexport const mark = async (targetElement: HTMLElement): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute(SPECCER_DATA_ATTRIBUTE) || '';\n\n await waitForFrame();\n\n const _options = getOptions(_areas_string, getComputedStyle(targetElement));\n\n if (_options.type !== 'mark') return;\n\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n const _mark_element = create(_pin_element_id);\n\n document.body.appendChild(_mark_element);\n\n const _positional_styles = await getRec(_mark_element, targetElement);\n const { left, top, height, width } = _positional_styles.absolute();\n const _mark_styles = {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width}px`\n };\n\n await addStyles(_mark_element, _mark_styles);\n};\n","/* node:coverage disable */\n/**\n * This feature measures given element\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"measure [height left|right] | [width top|bottom]\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * measure: {\n * height: true\n * }\n * };\n *\n * measure(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { MeasureAreaEnum } from '../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { cx, set as setClassNames } from '../../utils/classnames';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { getRec } from '../../utils/position';\nimport { 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 {SpeccerOptionsInterface} options - The options.\n * @param {string} id - The element id.\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 options: SpeccerOptionsInterface,\n id: string,\n tag = 'span'\n): HTMLElement => {\n const _el = document.createElement(tag);\n\n _el.setAttribute('title', `${text}px`);\n _el.setAttribute('id', id);\n _el.setAttribute('data-measure', `${parseInt(String(text), 10)}px`);\n\n const { measure, position } = options;\n const _class_names = cx('ph-speccer speccer measure', {\n height: measure?.height || false,\n width: measure?.width || false,\n slim: measure?.slim || false,\n [position]: true\n });\n\n setClassNames(_el, _class_names);\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 based on the attribute values from `data-speccer`.\n *\n * \n *\n * @param {HTMLElement} targetElement - The target element to match styles with.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<void>} - A promise that resolves after creating and styling the measurement element.\n *\n * @example\n * ##### Height to the right\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * measure: {\n * height: true\n * }\n * };\n *\n * measure(targetElement,options);\n * ```\n *\n * ##### Slim width to the bottom\n *\n * \n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'bottom',\n * measure: {\n * slim: true,\n * width: true\n * }\n * };\n *\n * measure(targetElement,options);\n * ```\n */\nexport const measure = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _options = getOptions(\n _areas_string,\n getComputedStyle(targetElement),\n options\n );\n\n if (_options.type !== 'measure' || !_options.measure) return;\n\n const { measure, position } = _options;\n\n await waitForFrame();\n\n const _target_rect = targetElement.getBoundingClientRect();\n const _width_modifier = !measure.slim ? 48 : 0;\n const _height_modifier = !measure.slim ? 96 : 0;\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n if (measure.width) {\n if (position === MeasureAreaEnum.Bottom) {\n const _measure_el = create(_target_rect.width, _options, _pin_element_id);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\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 { left, top, width, height } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height + _width_modifier}px`\n });\n }\n } else {\n const _measure_el = create(_target_rect.width, _options, _pin_element_id);\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\n const { left, top, width } = _positional_styles.fromTop({\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 { left, top, width, height } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top - _width_modifier}px`,\n width: `${width}px`,\n height: `${height + _width_modifier}px`\n });\n }\n }\n } else if (measure.height) {\n if (position === MeasureAreaEnum.Right) {\n const _measure_el = create(\n _target_rect.height,\n _options,\n _pin_element_id\n );\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\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 { left, top, height, width } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width + _height_modifier}px`\n });\n }\n } else {\n const _measure_el = create(\n _target_rect.height,\n _options,\n _pin_element_id\n );\n\n document.body.appendChild(_measure_el);\n\n const _positional_styles = await getRec(_measure_el, targetElement);\n\n if (measure.slim) {\n const { left, top, height } = _positional_styles.fromLeft({\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 { left, top, height, width } = _positional_styles.absolute({\n center: false\n });\n\n await addStyles(_measure_el, {\n left: `${left - _height_modifier}px`,\n top: `${top}px`,\n height: `${height}px`,\n width: `${width + _height_modifier}px`\n });\n }\n }\n }\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { set as setClassNames, cx } from '../../../utils/classnames';\n\n/**\n * Create a pin element with optional content, area description, and element type.\n *\n * @param {string} content - The content to add to the element.\n * @param {SpeccerOptionsInterface} options - The option for styling.\n * @param {string} id - The id of the pinned element\n * @param {string} n - The element type.\n * @returns {HTMLElement} - The created pin element.\n *\n * @example\n * ```ts\n * const pinElement = createPinElement('A', 'outline top', 'div');\n * document.body.appendChild(pinElement);\n * ```\n */\nexport const createPinElement = (\n content = '',\n options: SpeccerOptionsInterface,\n id = '',\n n = 'span'\n): HTMLElement => {\n const _el = document.createElement(n);\n const _extra_class_names: Record<string, boolean> = {};\n const { position, pin = {} as Record<string, boolean> } = options;\n const {\n useSVGLine,\n useCurlyBrackets,\n text,\n parent,\n bracket,\n enclose,\n subtle\n } = pin;\n\n _extra_class_names['text'] = text;\n _extra_class_names['parent'] = parent;\n _extra_class_names['bracket'] = bracket;\n _extra_class_names['enclose'] = enclose;\n _extra_class_names['subtle'] = subtle;\n _extra_class_names['svg'] = useSVGLine;\n _extra_class_names['curly'] = useCurlyBrackets;\n _extra_class_names[position] = true;\n\n if (parent && !bracket && !useCurlyBrackets && !subtle)\n _extra_class_names.svg = true;\n\n if ((!bracket && !enclose) || (bracket && useCurlyBrackets))\n _el.innerHTML = content;\n else if (bracket || enclose) _el.setAttribute('data-pin-counter', content);\n\n const _class_names = cx('ph-speccer speccer pin', _extra_class_names);\n\n setClassNames(_el, _class_names);\n\n _el.setAttribute('id', id);\n\n return _el;\n};\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","import { SpeccerOptionsInterface } from '../../types/speccer';\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 options: SpeccerOptionsInterface;\n\n /**\n * Creates a new DrawCircle instance.\n * @param {HTMLElement} el - The element used to position the circle.\n * @param {number} radius - The radius of the circle\n * @param {SpeccerOptionsInterface} options - The options used to identify position\n */\n constructor(\n el: HTMLElement,\n radius: number,\n options: SpeccerOptionsInterface\n ) {\n this.#init(el, radius, options);\n }\n\n /**\n * Initializes the DrawCircle instance.\n * @param {HTMLElement} el - The element used to position the circle.\n * @param {number} radius - The radius of the circle\n * @param {SpeccerOptionsInterface} options - The options 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, options: SpeccerOptionsInterface) {\n if (!el || !radius || !options) {\n throw new Error('Missing inputs el or radius or options');\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.options = options;\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 const { x, y } = await intrinsic_coords(this.el, this.options.position);\n\n this.circle.setAttribute('r', this.radius + ''); // SVG attributes\n this.circle.setAttribute('cx', Math.round(x) + ''); // SVG attributes\n this.circle.setAttribute(\n 'cy',\n Math.round(y + document.documentElement.scrollTop) + ''\n ); // 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 CoordinatesForBezierObjectType,\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 {CreateCoordinatesForCurveCoordParamType} coords - The coordinates of the start and end points.\n * @param {CreateCoordinatesForCurveOptionsParamType} 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): CoordinatesForBezierObjectType => {\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 if (!direct) {\n return {\n firstPoint,\n firstControl: { x: x1 + (x2 - x1) / 2, y: y1 }, // Control point for the first point\n lastPoint,\n lastControl: { x: x1 + (x2 - x1) / 2, y: y2 }\n };\n }\n\n if (firstSet) {\n if (direction === 'west') {\n return {\n firstPoint,\n firstControl: { x: x1 - 32, y: y1 - 16 / 2 },\n lastPoint,\n lastControl: { x: x2 + 32, y: y2 }\n };\n } else if (direction === 'south') {\n return {\n firstPoint,\n firstControl: { x: x1 - 16 / 2, y: y1 + 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 - 32 }\n };\n } else if (direction === 'east') {\n return {\n firstPoint,\n firstControl: { x: x1 + 32, y: y1 - 16 / 2 },\n lastPoint,\n lastControl: { x: x2 - 32, y: y2 }\n };\n } else {\n return {\n firstPoint,\n firstControl: { x: x1 - 16 / 2, y: y1 - 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 + 32 }\n };\n }\n } else {\n if (direction === 'west') {\n return {\n firstPoint,\n firstControl: { x: x1 - 32, y: y1 + 16 / 2 },\n lastPoint,\n lastControl: { x: x2 + 32, y: y2 }\n };\n } else if (direction === 'south') {\n return {\n firstPoint,\n firstControl: { x: x1 + 16 / 2, y: y1 + 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 - 32 }\n };\n } else if (direction === 'east') {\n return {\n firstPoint,\n firstControl: { x: x1 + 32, y: y1 + 16 / 2 },\n lastPoint,\n lastControl: { x: x2 - 32, y: y2 }\n };\n } else {\n return {\n firstPoint,\n firstControl: { x: x1 + 16 / 2, y: y1 - 32 },\n lastPoint,\n lastControl: { x: x2, y: y2 + 32 }\n };\n }\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(\n {\n x1,\n x2,\n y1: y1 + document.documentElement.scrollTop,\n y2: y2 + document.documentElement.scrollTop\n },\n { direction: '' }\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 * 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 { SpeccerOptionsInterface } from '../../types/speccer';\nimport { 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 options: SpeccerOptionsInterface;\n line: SVGPathElement;\n\n /**\n * Creates a new DrawSVGLine instance.\n * @param {HTMLElement} startElement - The starting element for the line.\n * @param {HTMLElement} stopElement - The ending element for the line.\n * @param {SpeccerOptionsInterface} [options] - The ending element for the line.\n */\n constructor(\n startElement: HTMLElement,\n stopElement: HTMLElement,\n options: SpeccerOptionsInterface = {} as SpeccerOptionsInterface\n ) {\n this.#init(startElement, stopElement, options);\n }\n\n /**\n * Initializes the DrawSVGLine instance.\n * @param {HTMLElement} startElement - The starting element for the line.\n * @param {HTMLElement} stopElement - The ending element for the line.\n * @param {SpeccerOptionsInterface} [options] - 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(\n startElement: HTMLElement,\n stopElement: HTMLElement,\n options: SpeccerOptionsInterface = {} as SpeccerOptionsInterface\n ) {\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 this.options = options;\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 const { pin } = this.options;\n\n if (pin?.text) {\n _new_path.classList.add('text');\n }\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 no-console:0 */\nimport {\n SpacingCSSPropertiesType,\n TypographyCSSPropertiesType\n} from '../types/css';\nimport { SpeccerOptionsInterface } from '../types/speccer';\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 * @param {SpeccerOptionsInterface|undefined} [options] - Options\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 options?: SpeccerOptionsInterface | undefined\n): SpacingCSSPropertiesType => {\n const {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n } = style;\n\n if (options?.spacing?.padding) {\n return {\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight\n };\n }\n\n if (options?.spacing?.margin) {\n return {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight\n };\n }\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 { PinAreaEnum } from '../../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { SpeccerStylesReturnType } from '../../../types/styles';\nimport { pinSpace, measureSize } from '../../../utils/css';\nimport { getRec } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Get styles for pin elements based on the specified area and options.\n *\n * @param {HTMLElement} targetElement - The target element.\n * @param {HTMLElement} pinElement - The pin element.\n * @param {HTMLElement} parentElement - The parent element.\n * @param {SpeccerOptionsInterface} options - The 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 pinElement = document.getElementById('pin');\n * const options = { useCurlyBrackets: true };\n * const styles = await styles(area, targetElement, pinElement, parentElement, options);\n * console.log(styles);\n * ```\n */\nexport const styles = async (\n targetElement: HTMLElement,\n pinElement: HTMLElement,\n parentElement: HTMLElement,\n options: SpeccerOptionsInterface\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const { pin = {} as Record<string, boolean>, position } = options;\n const { useCurlyBrackets, subtle, bracket, text, parent, enclose } = pin;\n const SPECCER_PIN_SPACE = pinSpace(pinElement);\n const SPECCER_MEASURE_SIZE = measureSize(pinElement);\n const _positional_styles = await getRec(pinElement, targetElement);\n\n if (enclose) {\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 ((parent || text) && !bracket && !useCurlyBrackets && !subtle) {\n if (position === PinAreaEnum.Right) {\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 (position === PinAreaEnum.Bottom) {\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 (position === PinAreaEnum.Left) {\n const { top } = _positional_styles.fromLeft({\n center: true\n });\n\n await waitForFrame();\n\n const { left } = parentElement.getBoundingClientRect();\n\n return {\n // If we're pinning with text only, we need to move the element a bit further to the left\n left: `${left - SPECCER_PIN_SPACE * 1.5 - (text ? 170 : 0)}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 (position === PinAreaEnum.Left) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (position === PinAreaEnum.Right) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (position === PinAreaEnum.Bottom) {\n if (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? 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 (bracket && !useCurlyBrackets) {\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: useCurlyBrackets ? SPECCER_PIN_SPACE / 1.5 : SPECCER_PIN_SPACE\n });\n\n return {\n left: `${left}px`,\n top: `${top}px`\n };\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\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 { createPinElement } from './create-pin-element';\nimport { styles } from './styles';\n\n/**\n * Create and style the pin element as needed.\n *\n * This function appends a new pin element to the document body based on the `data-speccer=\"pin\"` attribute\n * of the target element. It handles different styles, such as curly brackets or lines, based on the pin type.\n *\n * @param {HTMLElement} targetElement - The target element that contains the pin data.\n * @param {HTMLElement} parentElement - The parent element\n * @param {string} content - The content to use.\n * @param {SpeccerOptionsInterface} options - options\n * @returns {Promise<string|void>} A promise that resolves to the id of the pin element when the process is completed, or `void` if required input is invalid.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * const parentElement = document.getElementById('parent');\n * const content = 0;\n * const options = { … };\n * pinElement(targetElement, parentElement, content, options).then(() => {\n * console.log('process completed');\n * });\n * ```\n */\nexport const pinElement = async (\n targetElement: HTMLElement,\n parentElement: HTMLElement,\n content: string,\n options: SpeccerOptionsInterface\n): Promise<string | void> => {\n if (!targetElement) return;\n\n if (options.type !== 'pin' || !options.pin) return;\n\n const _pin_element_id = `speccer-${options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n const _pin_element = createPinElement(content, options, _pin_element_id);\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n document.body.appendChild(_pin_element);\n\n const _pin_styles = await styles(\n targetElement as HTMLElement,\n _pin_element,\n parentElement,\n options\n );\n\n await add(_pin_element, _pin_styles);\n\n const isText =\n options.pin.text &&\n targetElement.getAttribute('data-speccer-title') !== null;\n const _should_draw_circle =\n options.pin.parent &&\n !options.pin.enclose &&\n !options.pin.bracket &&\n !isText;\n\n if (options.pin.useSVGLine) {\n new DrawSVGLine(targetElement as HTMLElement, _pin_element, options);\n\n if (_should_draw_circle) new DrawCircle(targetElement, 5, options);\n } else if (options.pin.useCurlyBrackets) {\n new DrawSVGCurlyBracket(targetElement as HTMLElement, _pin_element);\n }\n\n return _pin_element_id;\n};\n","let _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 * @param {string|string[]} literalsToUse - Literals to use\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 = (\n targetIndex: number,\n literalsToUse: string | string[]\n): string => {\n let _character_to_use = literalsToUse[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 = `${literalsToUse[_index_to_use]}${literalsToUse[\n _index_to_use\n ].toLowerCase()}`;\n _index_to_use++;\n }\n\n return _character_to_use;\n};\n","/* node:coverage disable */\n/**\n * This feature annotate or highlight the anatomy of an element.\n *\n * \n *\n * In your component examples, use the following attribute. Remember to use the `data-speccer=\"pin-area\"`-attribute on a parent element to scope the marking.\n *\n * @example\n * ```html\n * <div data-speccer=\"pin-area\">\n * <div\n * data-speccer=\"pin [bracket [curly] |enclose] [left|right|top|bottom]\"\n * class=\"...\"\n * ></div>\n * </div>\n * ```\n *\n * @packageDocumentation\n */\n// eslint-disable-next-line import/no-unused-modules\n/* node:coverage enable */\nexport { createPinElement } from './utils/create-pin-element';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { pinElement } from './utils/pin-element';\n\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { SPECCER_LITERALS } from '../../utils/constants';\nimport { getOptions } from '../../utils/get-options';\nimport { isElementHidden } from '../../utils/node';\nimport { waitForFrame } from '../../utils/wait';\n\nimport { getCharacterToUse } from './utils/get-character-to-use';\nimport { getContentForPin } from './utils/get-content-for-pin';\nimport { pinElement } from './utils/pin-element';\n\n/**\n * Create pinned elements based on the section element and its data-speccer attributes.\n *\n * @param {HTMLElement} sectionElement - The section element containing pinned elements.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<void>} - A promise that resolves after creating pinned elements.\n *\n * @example\n * ```ts\n * const sectionElement = document.getElementById('section');\n * pinElements(sectionElement);\n * ```\n */\nexport const pinElements = async (\n sectionElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!sectionElement) return;\n\n const _els_to_be_pinned = sectionElement.querySelectorAll(\n '[data-speccer^=\"pin\"]'\n );\n\n if (!_els_to_be_pinned || _els_to_be_pinned.length === 0) return;\n\n const _literals_to_use =\n (sectionElement.getAttribute('data-speccer-literals') as string | null) ||\n window.SPECCER_LITERALS ||\n SPECCER_LITERALS;\n\n [..._els_to_be_pinned]\n .filter(\n async (targetElement: HTMLElement) => !isElementHidden(targetElement)\n )\n .forEach(\n async (\n targetElement: HTMLElement,\n targetIndex: number\n ): Promise<void> => {\n const _symbol = getCharacterToUse(targetIndex, _literals_to_use);\n const _areas_string = targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _target_style = getComputedStyle(targetElement);\n const _options = getOptions(_areas_string, _target_style, options);\n const _content = getContentForPin(_symbol, targetElement, _options);\n\n await pinElement(targetElement, sectionElement, _content, _options);\n }\n );\n};\n","import { SpeccerOptionsInterface } from '../../../types/speccer';\n\n/**\n * Generates the content for a pin element based on the provided symbol, target element, and options.\n *\n * @param {string} symbol - The default symbol to use if no text or description is provided.\n * @param {HTMLElement} targetElement - The HTML element for which the content is being generated.\n * @param {SpeccerOptionsInterface} options - The options that define how the content should be generated.\n * @returns {string} The generated content for the pin element.\n *\n * @example\n * ```ts\n * const symbol = '★';\n * const targetElement = document.getElementById('myElement');\n * const options = { pin: { text: true } };\n * const content = getContentForPin(symbol, targetElement, options);\n * console.log(content);\n * // Output: '<span class=\"ph-speccer title\">Title Text</span>'\n * ```\n */\nexport const getContentForPin = (\n symbol: string,\n targetElement: HTMLElement,\n options: SpeccerOptionsInterface\n): string => {\n const { pin } = options;\n\n if (!pin) return symbol;\n\n const { text } = pin;\n const _is_text =\n text && targetElement.getAttribute('data-speccer-title') !== null;\n\n if (!_is_text) return symbol;\n\n const _title = targetElement.getAttribute('data-speccer-title');\n const _description = targetElement.getAttribute('data-speccer-description');\n const _heading =\n targetElement.nodeName.indexOf('H') === 0\n ? `<span class=\"ph-speccer heading\">${targetElement.nodeName}</span>`\n : '';\n\n if (!_description && _title)\n return `${_heading}<span class=\"ph-speccer title\">${_title}</span>`;\n\n if (_description && _title)\n return `${_heading}<span class=\"ph-speccer title\">${_title}</span><span class=\"ph-speccer description\">${_description.replaceAll('\\\\n', '<br/>')}</span>`;\n\n return symbol;\n};\n","/* node:coverage disable */\n/**\n * This feature highlights the spacing of an element.\n *\n * \n * *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"spacing [padding|margin][bound]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n * @packageDocumentation\n */\n/* eslint no-console:0 */\n/* node:coverage enable */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { cx, set as setClassNames } from '../../utils/classnames';\nimport {\n getSpacing,\n getClassNameFromCSSProperty,\n getNumberValue\n} from '../../utils/css';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { get as getStyles, add as addStyles } 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}px`);\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 * \n *\n * @param {HTMLElement} targetElement - The target element to create spacing elements for.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options\n * @returns {Promise<void>} - A promise that resolves after creating and positioning the spacing elements.\n *\n * @example\n *\n * ##### Default, padding and margin\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * element(targetElement);\n * ```\n *\n * ##### Only padding\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * spacing: {\n * padding: true\n * }\n * };\n *\n * element(targetElement, options);\n *\n * ##### Bound style, like the old feature\n *\n * \n *\n * This option binds the speccer elements to the bounds of the element container.\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * spacing: {\n * bound: true,\n * }\n * };\n *\n * element(targetElement, options);\n * ```\n */\nexport const spacing = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n const _target_styles = await getStyles(targetElement);\n const _options = getOptions(_areas_string, _target_styles, options);\n\n if (_options.type !== 'spacing' || !_options.spacing) return;\n\n const _target_spacing_styles = getSpacing(_target_styles, _options);\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 targetElement.classList.add('is-specced');\n\n const _pin_element_id = `speccer-spacing-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n _target_pruned_spacing_styles.forEach(async (property) => {\n const _value = getNumberValue(_target_spacing_styles[property]);\n const _speccer_el = create(_value);\n\n _speccer_el.setAttribute('data-speccer-id', _pin_element_id);\n\n const _class_name = getClassNameFromCSSProperty(property);\n\n setClassNames(\n _speccer_el,\n cx(_class_name, {\n bound: _options?.spacing?.bound ? true : false\n })\n );\n document.body.appendChild(_speccer_el);\n\n const _styles = await position(property, _value, targetElement, _options);\n\n await addStyles(_speccer_el, _styles as object);\n });\n};\n","import { PositionUnitPropertiesType } from '../../../types/position';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\nimport { offset } from '../../../utils/position';\nimport { waitForFrame } from '../../../utils/wait';\n\n/**\n * Set the position and dimensions of a spacing element relative to a target element.\n *\n * @param {string} property - The CSS property to set (e.g., 'marginTop', 'marginLeft', etc.).\n * @param {number} value - The value of the CSS property.\n * @param {HTMLElement} targetElement - The target element.\n * @param {SpeccerOptionsInterface|undefined} [options] - Options.\n * @returns {Promise<PositionUnitPropertiesType|undefined>} - A promise that resolves after setting the position and dimensions.\n *\n * @example\n * ```ts\n * const targetElement = document.getElementById('target');\n * position('marginTop', 20, targetElement);\n * ```\n */\nexport const position = async (\n property: string,\n value: number,\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<PositionUnitPropertiesType | undefined> => {\n await waitForFrame();\n\n const _target_rect = targetElement.getBoundingClientRect();\n const _target_offset = await offset(targetElement);\n const _width_modifier = options?.spacing?.bound ? 0 : 96;\n const _height_modifier = options?.spacing?.bound ? 0 : 48;\n\n if (property === 'marginTop')\n return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top - value + 'px'\n };\n\n if (property === 'marginRight')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top + parseInt(_target_rect.height + '', 10) + 'px'\n };\n\n if (property === 'marginLeft')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top: _target_offset.top + 'px'\n };\n\n if (property === 'paddingBottom')\n return {\n height: `${value}px`,\n width: _target_rect.width + _width_modifier + 'px',\n left: _target_offset.left - _width_modifier + 'px',\n top:\n _target_offset.top +\n (parseInt(_target_rect.height + '', 10) - value) +\n 'px'\n };\n\n if (property === 'paddingRight')\n return {\n height: _target_rect.height + _height_modifier + '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 return {\n height: _target_rect.height + _height_modifier + 'px',\n width: `${value}px`,\n left: _target_offset.left + 'px',\n top: _target_offset.top + 'px'\n };\n\n return undefined;\n};\n","/* node:coverage disable */\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 */\n/* node:coverage enable */\nexport const decimal = (number: string | number, decimals = 3): string =>\n parseFloat(String(number)).toFixed(decimals);\n","/**\n * This feature presents typography\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"typography [top|right|bottom|left] [syntax]\"\n * class=\"...\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * const options = {\n * position: 'right',\n * type: 'typography',\n * typography: {\n * useSyntaxHighlighting: false\n * }\n * };\n *\n * typography(targetElement, options);\n * ```\n *\n * @packageDocumentation\n */\n/* eslint-disable import/no-unused-modules */\n/* eslint no-console:0 */\nimport { SpeccerOptionsInterface } from '../../types/speccer';\nimport { set as setClassNames, cx } from '../../utils/classnames';\nimport { getOptions } from '../../utils/get-options';\nimport { uniqueID } from '../../utils/id';\nimport { isElementHidden } from '../../utils/node';\nimport { add as addStyles } from '../../utils/styles';\nimport { waitForFrame } from '../../utils/wait';\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 {SpeccerOptionsInterface} options - Options.\n * @param {string} id - The id.\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 = (\n html: string,\n options: SpeccerOptionsInterface,\n id: string\n): HTMLElement => {\n const _el = document.createElement('div');\n const { typography, position } = options;\n const _class_names = cx('ph-speccer speccer typography', {\n syntax: typography?.useSyntaxHighlighting || false,\n [position]: true\n });\n\n _el.setAttribute('id', id);\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 * \n *\n * @param {HTMLElement} targetElement - The target element to specc typography for.\n * @param {SpeccerOptionsInterface|undefined} [options] - Custom options\n * @returns {Promise<void>} - A promise that resolves once typography element is created and positioned.\n *\n * @example\n *\n * ##### Default\n *\n * ```ts\n * const targetElement = document.querySelector('.target');\n * if (targetElement) {\n * element(targetElement);\n * }\n * ```\n *\n * ##### With syntax higlight feature\n *\n * \n *\n * ```ts\n * const targetElement = document.querySelector('.target');\n * const options = {\n * typography : {\n * useSyntaxHighlighting: true\n * }\n * };\n *\n * if (targetElement) {\n * element(targetElement, options);\n * }\n * ```\n */\nexport const typography = async (\n targetElement: HTMLElement,\n options?: SpeccerOptionsInterface | undefined\n): Promise<void> => {\n if (!targetElement) return;\n\n if (isElementHidden(targetElement)) return;\n\n const _areas_string: string =\n targetElement.getAttribute('data-speccer') || '';\n\n await waitForFrame();\n\n const _options = getOptions(\n _areas_string,\n getComputedStyle(targetElement),\n options\n );\n\n if (_options.type !== 'typography' || !_options.typography) return;\n\n targetElement.classList.add('is-specced');\n\n const _html = await template(\n targetElement,\n _options.typography.useSyntaxHighlighting\n );\n const _pin_element_id = `speccer-${_options.slug}-${targetElement.getAttribute('id') || uniqueID()}`;\n\n targetElement.setAttribute('data-speccer-element-id', _pin_element_id);\n\n const _speccer_el = create(_html, _options, _pin_element_id);\n\n document.body.appendChild(_speccer_el);\n\n const _position = await position(_options, targetElement, _speccer_el);\n\n addStyles(_speccer_el, _position);\n};\n","import { getTypography } from '../../../utils/css';\nimport { get as getStyles } from '../../../utils/styles';\n\n/* node:coverage disable */\n/**\n * Generate a HTML string for typography styles of a target element.\n *\n * @param {HTMLElement} targetElement - 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 */\n/* node:coverage enable */\nexport const template = async (\n targetElement: HTMLElement,\n useHighlighting = false\n): Promise<string> => {\n const _target_styles = await getStyles(targetElement);\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 { TypographyAreaEnum } from '../../../types/enums/area';\nimport { SpeccerOptionsInterface } from '../../../types/speccer';\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 {SpeccerOptionsInterface} options - Options.\n * @param {HTMLElement} targetElement - The target element.\n * @param {HTMLElement} speccerElement - 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 options = {…};\n * const position = await position(options, targetElement, speccerElement);\n * console.log(position); // { left: '10px', top: '20px' }\n * ```\n */\nexport const position = async (\n options: SpeccerOptionsInterface,\n targetElement: HTMLElement,\n speccerElement: HTMLElement\n): Promise<{ left: string; top: string }> => {\n const _target_rect = targetElement.getBoundingClientRect();\n const SPECCER_PIN_SPACE = pinSpace(speccerElement);\n const _speccer_el_rect = speccerElement.getBoundingClientRect();\n const _el_offset = await offset(targetElement);\n const { typography, position } = options;\n\n if (typography && position === TypographyAreaEnum.Right) {\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(\n _el_offset.top,\n _speccer_el_rect,\n _target_rect\n )\n ) + 'px';\n\n return {\n left: _right_layout_position_left,\n top: _right_layout_position_top\n };\n }\n\n if (typography && position === TypographyAreaEnum.Top) {\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\n return {\n left: _top_layout_position_left,\n top: _top_layout_position_top\n };\n }\n\n if (typography && position === TypographyAreaEnum.Bottom) {\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 return {\n left: _bottom_layout_position_left,\n top: _bottom_layout_position_top\n };\n }\n\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\n return {\n left: _left_layout_position_left,\n top: _left_layout_position_top\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","/* node:coverage disable */\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 */\n/* node:coverage enable */\nimport { grid as gridElement } from '../features/grid';\nimport { mark as markElement } from '../features/mark';\nimport { measure as measureElement } from '../features/measure';\nimport { pinElements } from '../features/pin';\nimport { spacing as spacingElement } from '../features/spacing';\nimport { typography as typographyElement } from '../features/typography';\nimport { SpeccerFunctionType } from '../types/speccer';\nimport {\n SPECCER_DATA_ATTRIBUTE,\n SPECCER_FEATURE_GRID,\n SPECCER_FEATURE_MARK,\n SPECCER_FEATURE_MEASURE,\n SPECCER_FEATURE_PIN_AREA,\n SPECCER_FEATURE_SPACING,\n SPECCER_FEATURE_TYPOGRAPHY\n} from '../utils/constants';\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 _spacing_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n spacingElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"],[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)`\n )) {\n _spacing_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(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MEASURE}\"]`\n )) {\n _measure_observer.observe(el);\n }\n\n const _mark_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n markElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MARK}\"]`\n )) {\n _mark_observer.observe(el);\n }\n\n const _typography_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n typographyElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_TYPOGRAPHY}\"]`\n )) {\n _typography_observer.observe(el);\n }\n\n const _grid_observer = new IntersectionObserver((els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n gridElement(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_GRID}\"]`\n )) {\n _grid_observer.observe(el);\n }\n\n const _pin_observer = new IntersectionObserver(async (els, observer) => {\n for (const el of els) {\n if (el.intersectionRatio > 0) {\n await pinElements(el.target as HTMLElement);\n observer.unobserve(el.target);\n }\n }\n });\n\n for (const el of document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}=\"${SPECCER_FEATURE_PIN_AREA}\"]`\n )) {\n _pin_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, form, main, nav, aside, [role=\"section\"], [role=\"banner\"],\n[role=\"complementary\"], [role=\"contentinfo\"], [role=\"form\"], [role=\"main\"],\n[role=\"navigation\"], [role=\"region\"], [role=\"search\"]\n`;\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} targetElement - Target HTML element.\n * @param {HTMLElement} a11yElement - 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 targetElement: HTMLElement,\n a11yElement: HTMLElement\n): Promise<SpeccerStylesReturnType> => {\n await waitForFrame();\n\n const SPECCER_PIN_SPACE = pinSpace(a11yElement);\n const _positional_styles = await getRec(a11yElement, targetElement);\n\n if (type === 'tabstops') {\n let { left, top } = _positional_styles.fromTop();\n\n left -= 32;\n top += 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' || type === 'autocomplete' || type === 'headings' ) {\n let { left, top } = _positional_styles.fromLeft();\n\n\n\n\n left -= SPECCER_PIN_SPACE;\n\n\n if (left <= 0) left = SPECCER_PIN_SPACE;\n\n if (top <= 0) top = SPECCER_PIN_SPACE;\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","import { add } from '../../../utils/styles';\n\nimport { createA11yElement } from './create-a11y-element';\nimport { getRole } from './get-role';\nimport { styles } from './styles';\n\n\n/**\n * Adds an accessibility element to the document body based on the target element and type.\n *\n * \n * \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 addA11yElement(targetElement, 1, 'landmark');\n * await addA11yElement(targetElement, null, 'tabstops');\n * }\n * ```\n */\nexport const addA11yElement = async (\n targetEl: HTMLElement,\n content: unknown,\n type: string\n): Promise<void> => {\n if (!targetEl || !targetEl.checkVisibility()) return;\n\n const _a11y_el = createA11yElement(type, content);\n\n if (type === 'landmark') {\n const _role = getRole(targetEl);\n const _node_name = targetEl.nodeName.toLowerCase();\n\n _a11y_el.innerHTML = `<${_node_name} role=\"${_role}\">`;\n }\n\n if (type === 'autocomplete') {\n const _autocomplete = targetEl.getAttribute('autocomplete') || '';\n\n _a11y_el.innerHTML = `autocomplete=\"${_autocomplete}\"`;\n }\n\n if (type === 'headings') {\n _a11y_el.innerHTML = targetEl.nodeName;\n _a11y_el.classList.add(targetEl.nodeName.toLowerCase());\n }\n\n if (type === 'tabstops') {\n _a11y_el.setAttribute('data-speccer-a11y-tabstops', content as string);\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","import { set as setClassNames, cx } from '../../../utils/classnames';\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 createA11yElement = (\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 autocomplete: type === 'autocomplete',\n headings: type === 'headings',\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","/* node:coverage disable */\n/**\n * Retrieves the role of a given HTML element.\n *\n * This function first checks if the `role` attribute of the target element is defined and not empty.\n * If the `role` attribute is not available, it maps certain semantic HTML elements to their respective\n * roles (e.g., `<header>` -> `'header'`). If the element does not match any predefined roles, it returns `'N/A'`.\n *\n * @param {HTMLElement} targetEl - The target HTML element whose role is to be determined.\n * @returns {string} The role of the element, or `'N/A'` if no role is applicable.\n *\n * @example\n * ```ts\n * const element = document.createElement('header');\n * const role = getRole(element);\n * console.log(role); // Output: 'header'\n *\n * const divElement = document.createElement('div');\n * divElement.setAttribute('role', 'button');\n * const divRole = getRole(divElement);\n * console.log(divRole); // Output: 'button'\n *\n * const spanElement = document.createElement('span');\n * const spanRole = getRole(spanElement);\n * console.log(spanRole); // Output: 'N/A'\n * ```\n */\n/* node:coverage enable */\nexport const getRole = (targetEl:HTMLElement): string => {\n if(!targetEl) return '';\n\n if(targetEl.role && targetEl.role !== '') return targetEl.role;\n\n const _node_name = targetEl.nodeName.toLowerCase();\n\n if(['header', 'footer', 'section', 'form', 'main', 'nav', 'aside'].includes(_node_name)) return _node_name;\n\n return 'N/A';\n};\n","import { cx, set as setClassNames } from '../../../utils/classnames';\nimport { add } from '../../../utils/styles';\nimport { SPECCER_MODIFIER_KEYS, SPECCER_PHYSICAL_KEYS } from '../constants';\n\nimport { styles } from './styles';\n\n/**\n * Adds a shortcut element to the document body based on the provided HTML element and shortcut string.\n *\n * \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 addShortcutElement(shortcutElement, 'Ctrl + Shift + A');\n * }\n * ```\n */\nexport const addShortcutElement = 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 const _shortcut_holder_class_names = cx(\n 'ph-speccer speccer a11y shortcut-holder'\n );\n\n setClassNames(_shortcut_holder, _shortcut_holder_class_names);\n\n for (const key of _keys) {\n const _key_element = document.createElement('kbd');\n const _key_text_node = document.createTextNode(key);\n const _key_element_class_names = cx('ph-speccer speccer a11y shortcut', {\n modifier: SPECCER_MODIFIER_KEYS.includes(key.toLowerCase()),\n physical: SPECCER_PHYSICAL_KEYS.includes(key.toLowerCase())\n });\n\n setClassNames(_key_element, _key_element_class_names);\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 * Remove a speccer element by removing associated elements and SVG paths.\n *\n * This function removes any speccer elements linked to the specified element and\n * also removes any SVG paths that might be associated with it.\n *\n * @param {HTMLElement} el - The HTML element to unpin.\n * @returns {void} This function does not return a value.\n *\n * @example\n * ```ts\n * const element = document.getElementById('my-element');\n * if (element) {\n * removeSpeccerElement(element);\n * }\n * ```\n */\nexport const removeSpeccerElement = (el: HTMLElement): void => {\n const _selector = el.getAttribute('data-speccer-element-id');\n\n if (!_selector) return;\n\n const _pin_element =\n document.getElementById(_selector) ||\n document.querySelectorAll(`[data-speccer-id=\"${_selector}\"]`);\n\n if (!_pin_element) return;\n\n if (Object.prototype.isPrototypeOf.call(NodeList.prototype, _pin_element)) {\n [...(_pin_element as unknown as HTMLElement[])].forEach(\n (el: HTMLElement) => {\n el.remove();\n el.classList.remove('is-specced');\n }\n );\n } else {\n // We also need to remove the svg paths if it is in use\n if (\n (_pin_element as HTMLElement).classList.contains('curly') ||\n (_pin_element as HTMLElement).classList.contains('svg')\n ) {\n const _el_ID = el.getAttribute('id');\n\n document\n .querySelectorAll(`#ph-speccer-svg path[data-start-el=\"${_el_ID}\"]`)\n .forEach((el) => el.remove());\n }\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 { a11y as initA11y } from './features/a11y';\nimport { create as gridCreate, grid as gridElement } from './features/grid';\nimport { create as markCreate, mark as markElement } from './features/mark';\nimport {\n create as measureCreate,\n measure as measureElement\n} from './features/measure';\nimport { createPinElement, pinElement, pinElements } from './features/pin';\nimport {\n create as spacingCreate,\n spacing as spacingElement\n} from './features/spacing';\nimport {\n create as typographyCreate,\n typography as typographyElement\n} from './features/typography';\nimport {\n SPECCER_DATA_ATTRIBUTE,\n SPECCER_FEATURE_GRID,\n SPECCER_FEATURE_MARK,\n SPECCER_FEATURE_MEASURE,\n SPECCER_FEATURE_PIN_AREA,\n SPECCER_FEATURE_SPACING,\n SPECCER_FEATURE_TYPOGRAPHY\n} from './utils/constants';\nimport { removeAll } from './utils/node';\n\n// eslint-disable-next-line import/no-unused-modules\nexport { removeSpeccerElement } from './utils/remove-speccer-element';\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 pin = {\n createPinElement,\n pinElement,\n pinElements\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 spacingElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_SPACING}\"]`\n );\n const measureElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MEASURE}\"]`\n );\n const typographyElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_TYPOGRAPHY}\"]`\n );\n const pinSectionElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}=\"${SPECCER_FEATURE_PIN_AREA}\"]`\n );\n const markElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_MARK}\"]`\n );\n const gridElements = document.querySelectorAll(\n `[${SPECCER_DATA_ATTRIBUTE}^=\"${SPECCER_FEATURE_GRID}\"]`\n );\n\n for (const el of markElements) {\n markElement(el as HTMLElement);\n }\n for (const el of gridElements) {\n gridElement(el as HTMLElement);\n }\n for (const el of spacingElements) {\n spacingElement(el as HTMLElement);\n\n if (el.hasChildNodes()) {\n const _child_spacing_elements = el.querySelectorAll(\n '*:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody):not([data-speccer])'\n );\n const _areas_string: string = el.getAttribute('data-speccer') || '';\n\n if (_child_spacing_elements && _child_spacing_elements.length) {\n for (const childEl of _child_spacing_elements) {\n childEl.setAttribute('data-speccer', _areas_string);\n spacingElement(childEl as HTMLElement);\n }\n }\n }\n }\n for (const el of measureElements) {\n measureElement(el as HTMLElement);\n }\n for (const el of typographyElements) {\n typographyElement(el as HTMLElement);\n }\n for (const el of pinSectionElements) {\n pinElements(el as HTMLElement);\n }\n initA11y();\n};\n\nexport default speccer;\n\nactivate(speccer);\n","/**\n * This feature will annotate or highlight accessibility areas like landmarks and region. It can also display tab stops/sequence and any keyboard shortcuts assigned\n *\n * \n *\n * @example\n *\n * Use the following code, either for html or js:\n *\n * ```html\n * <div\n * data-speccer=\"a11y [shortcuts|tabstops|landmark|headings|autocomplete]\"\n * class=\"…\"\n * >\n * …\n * </div>\n * ```\n *\n * ```ts\n * const targetElement = document.getElementById('target');\n * a11y(targetElement);\n * ```\n *\n * @packageDocumentation\n */\n\nimport { isElementHidden } from '../../utils/node';\n\nimport {\n SPECCER_LANDMARK_ELEMENTS_SELECTOR,\n SPECCER_TABBABLE_ELEMENTS_SELECTOR\n} from './constants';\nimport { addA11yElement } from './utils/add-a11y-element';\nimport { addShortcutElement } from './utils/add-shortcut-element';\n\n/**\n * Initializes the accessibility elements on the document.\n *\n * @example\n * ```ts\n * a11y();\n * ```\n */\nexport const a11y = () => {\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 const _autocomplete_elements = document.querySelectorAll(\n '[data-speccer*=\"a11y autocomplete\"]'\n );\n const _headings_elements = document.querySelectorAll(\n '[data-speccer*=\"a11y headings\"]'\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 (\n !_shortcut_string ||\n _shortcut_string === '' ||\n isElementHidden(el as HTMLElement)\n )\n continue;\n\n addShortcutElement(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 [tabstopsIndex, tabstopsEl] of _tabstops_els.entries()) {\n if (!isElementHidden(tabstopsEl as HTMLElement)) {\n addA11yElement(tabstopsEl as HTMLElement, tabstopsIndex + 1, 'tabstops');\n continue;\n }\n\n const id = tabstopsEl.getAttribute('id');\n\n if (!id) continue;\n\n const potentialLabelElement = document.querySelector(`[for=\"${id}\"]`);\n\n if (\n !potentialLabelElement ||\n isElementHidden(potentialLabelElement as HTMLElement)\n ) continue;\n\n // This could be a fake element, like a toggle checkbox, so we use the labelElement\n addA11yElement(potentialLabelElement as HTMLElement, tabstopsIndex + 1, 'tabstops');\n }\n }\n }\n\n if (_autocomplete_elements.length) {\n for (const el of _autocomplete_elements) {\n const _autocomplete_els = el.querySelectorAll(\n '[autocomplete]'\n );\n\n for (const _autocomplete_el of _autocomplete_els) {\n if (isElementHidden(_autocomplete_el as HTMLElement)) continue;\n\n addA11yElement(_autocomplete_el as HTMLElement, null, 'autocomplete');\n }\n }\n }\n\n if (_headings_elements.length) {\n for (const el of _headings_elements) {\n const _headings_els = el.querySelectorAll(\n 'h1,h2,h3,h4,h5,h6, [role=\"heading\"]'\n );\n\n for (const _headings_el of _headings_els) {\n if (isElementHidden(_headings_el as HTMLElement)) continue;\n\n addA11yElement(_headings_el as HTMLElement, null, 'headings');\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 if (isElementHidden(landmarkEl as HTMLElement)) continue;\n\n addA11yElement(landmarkEl as HTMLElement, landmarkIndex + 1, 'landmark');\n addA11yElement(landmarkEl as HTMLElement, null, 'region');\n }\n }\n }\n};\n"],"names":["isString","variable","isNotString","isNumber","isNotNumber","isUndefined","set","el","cls","avoid","length","preparedClassNames","trim","split","filter","cl","map","classList","add","cx","cls_obj","Object","keys","classname","join","SPECCER_LITERALS","SPECCER_DATA_ATTRIBUTE","SPECCER_FEATURE_SPACING","SPECCER_FEATURE_MEASURE","SPECCER_FEATURE_TYPOGRAPHY","SPECCER_FEATURE_MARK","SPECCER_FEATURE_GRID","SPECCER_FEATURE_PIN_AREA","SpeccerAreaEnum","PinAreaEnum","MeasureAreaEnum","TypographyAreaEnum","SpacingAreaEnum","MarkAreaEnum","GridAreaEnum","getAreasFromString","areaString","isBracketArea","includes","Bracket","isEncloseArea","Enclose","isSubtle","Subtle","isParentArea","Parent","isTextArea","Text","isHeightArea","Height","isSlimArea","Slim","isWidthArea","Width","useSVG","areas","SVG","isCurly","Curly","useSyntaxHighlighting","Syntax","getFeatureBasedOnArea","targetStyle","Pin","isValidPinElement","styles","Grid","display","isValidGridElement","Mark","isValidMarkElement","Measure","isValidMeasureElement","Spacing","isValidSpacingElement","Typography","isValidTypographyElement","getPositionBasedOnArea","Left","isLeftArea","Right","isRightArea","Bottom","isBottomArea","getOptions","customOptions","type","options","slug","str","normalize","replace","toLowerCase","ltr","idx","toUpperCase","position","bracket","enclose","subtle","parent","text","useSVGLine","useCurlyBrackets","slim","height","width","_toggle_value","getGridToggleValue","toggle","both","rows","columns","getSpacingToggleValue","margin","padding","bound","uniqueID","Math","random","toString","substring","isElementHidden","element","checkVisibility","opacityProperty","checkVisibilityCSS","waitForFrame","Promise","requestAnimationFrame","hasStylePropertySet","async","property","value","getComputedStyle","getParentWithStylePropertySet","parentElement","get_horizontal_center_of_els","modifier","startRect","targetRect","get_vertical_center_of_els","offset","targetEl","_target_rect","getBoundingClientRect","_el_offset_top","top","window","scrollY","_el_offset_left","left","scrollX","stickyParentElement","getParentThatIsSticky","isSticky","originalPosition","style","getRec","sourceEl","_source_rect","_target_offset","_target_offset_center","offsetWithCenter","_target_height","_target_width","_source_height","_source_width","absolute","toTop","center","sourceHeight","fromTop","toBottom","targetHeight","fromBottom","toLeft","sourceWidth","fromLeft","toRight","targetWidth","fromRight","Array","isArray","constructor","reduce","acc","st","key","assign","get","create","targetElement","grid","gridTemplateColumns","gridTemplateRows","_pin_element_id","getAttribute","setAttribute","columnGap","parseInt","gridColumnContainer","document","createElement","documentElement","setProperty","setClassNames","addStyles","numberOfColumnItems","i","gridItem","appendChild","body","rowGap","gridRowContainer","numberOfRowItems","_areas_string","_target_style","getStyles","_options","id","n","_mark_element","mark","_positional_styles","_mark_styles","tag","_el","String","measure","_class_names","_width_modifier","_height_modifier","_measure_el","createPinElement","content","_extra_class_names","pin","svg","innerHTML","coords","rect","xy","x","y","right","bottom","intrinsic_coords","pos","Error","_allowed_positions","_el_rect","DrawCircle","canvas","circle","radius","this","init","contains","getElementById","html","max","scrollHeight","offsetHeight","clientHeight","addStyle","draw","_circle_el_id","createElementNS","_el_ID","round","scrollTop","getCoordsPairFromObjects","el1","el2","pos1","pos2","x1","y1","x2","y2","createBezierCurveCoordinates","direct","firstSet","direction","firstPoint","lastPoint","firstControl","lastControl","getCurlySVGPath","startEl","stopEl","x2modifier","y2modifier","direction_of_element","start","stop","crude","_angle","cy","ex","ey","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","getNumberValue","pinSpace","getPropertyValue","pinElement","SPECCER_PIN_SPACE","SPECCER_MEASURE_SIZE","_pin_element","_pin_styles","isText","_should_draw_circle","_index_to_use","pinElements","sectionElement","_els_to_be_pinned","querySelectorAll","_literals_to_use","forEach","targetIndex","_symbol","literalsToUse","_character_to_use","getCharacterToUse","_content","symbol","_title","_description","_heading","nodeName","indexOf","replaceAll","getContentForPin","_text_content","createTextNode","spacing","_target_styles","_target_spacing_styles","marginTop","marginBottom","marginLeft","marginRight","paddingTop","paddingBottom","paddingLeft","paddingRight","getSpacing","_target_pruned_spacing_styles","_value","_speccer_el","_class_name","getClassNameFromCSSProperty","_styles","decimal","number","decimals","parseFloat","toFixed","typography","syntax","_html","useHighlighting","lineHeight","letterSpacing","fontFamily","fontSize","fontStyle","fontVariationSettings","fontWeight","getTypography","_fontFamily","font","_fontSize","_letterSpacing","_lineHeight","template","_position","speccerElement","_speccer_el_rect","_el_offset","Top","activate","speccer","speccerEventFunc","func","wait","immediate","timeout","context","args","callNow","clearTimeout","setTimeout","apply","debounce","removeEventListener","addEventListener","dom","readyState","lazy","_spacing_observer","IntersectionObserver","els","observer","intersectionRatio","spacingElement","target","unobserve","observe","_measure_observer","measureElement","_mark_observer","markElement","_typography_observer","typographyElement","_grid_observer","gridElement","_pin_observer","manual","_script","currentScript","_speccer_script_src","hasAttribute","resizeActivate","SPECCER_MODIFIER_KEYS","SPECCER_PHYSICAL_KEYS","a11yElement","addA11yElement","_a11y_el","tabstops","landmark","autocomplete","headings","region","_text_node","createA11yElement","_role","role","_node_name","getRole","_autocomplete","_a11y_styles","addShortcutElement","shortcutString","_keys","_shortcut_holder","_shortcut_holder_class_names","_key_element","_key_text_node","_key_element_class_names","physical","_shortcut_holder_styles","removeSpeccerElement","_selector","prototype","isPrototypeOf","call","NodeList","gridCreate","spacingCreate","measureCreate","markCreate","typographyCreate","modes","selector","e","removeAll","spacingElements","measureElements","typographyElements","pinSectionElements","markElements","gridElements","hasChildNodes","_child_spacing_elements","childEl","_tab_order_elements","_landmark_elements","_shortcut_elements","_autocomplete_elements","_headings_elements","_shortcut_string","_tabstops_els","tabstopsIndex","tabstopsEl","entries","potentialLabelElement","querySelector","_autocomplete_els","_autocomplete_el","_headings_els","_headings_el","_landmark_els","landmarkIndex","landmarkEl","initA11y"],"mappings":"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"}
|