{"version":3,"sources":["webpack://frontendplaceholder/./node_modules/split-type/dist/index.js"],"names":["extend","target","object","Object","getOwnPropertyNames","reduce","extended","key","currentValue","getOwnPropertyDescriptor","newValue","defineProperty","isString","value","isArray","Array","parseSettings","settings","types","undefined","split","String","map","type","trim","filter","test","absolute","position","parseTypes","none","lines","words","chars","isObject","isNode","input","nodeType","toArray","isLength","length","isArrayLike","prototype","slice","call","getTargetElements","elements","document","getElementById","querySelectorAll","result","element","append","nodes","i","node","this","appendChild","createTextNode","replaceChildren","lastChild","removeChild","replaceWith","parent","parentNode","ownerDocument","insertBefore","previousSibling","replaceChild","Element","DocumentFragment","entries","keys","values","expando","cache","uid","set","owner","console","warn","id","data","getPrototypeOf","get","remove","rsComboMarksRange","rsCombo","rsFitz","rsNonAstral","rsRegional","rsSurrPair","reOptMod","rsOptVar","rsSeq","join","rsSymbol","reUnicode","RegExp","reHasUnicode","hasUnicode","string","toChars","separator","match","unicodeToArray","asciiToArray","stringToArray","createElement","name","attributes","forEach","attribute","rawValue","setAttribute","defaults","splitClass","lineClass","wordClass","charClass","tagName","wordsAndChars","nodeValue","textNode","TAG_NAME","VALUE","splitText","createDocumentFragment","replace","toWords","WORD","idx","arr","wordElement","characterElementsForCurrentWord","CHAR","characterElement","class","style","children","isWord","isWordStart","isWordEnd","concat","splitWordsAndChars","childNodes","isRoot","display","nextSibling","prevSibling","text","textContent","textAfter","textBefore","child","unSplitWords","repositionAfterSplit","scrollPos","getElementsByTagName","wordsInEachLine","elementHeight","elementWidth","contentBox","wordsInCurrentLine","lineOffsetY","parentElement","nextElementSibling","cs","window","getComputedStyle","align","textAlign","lineThreshold","parseFloat","fontSize","left","offsetLeft","top","offsetTop","width","offsetWidth","offsetHeight","cssWidth","cssHeight","height","isWordLike","offsetParent","scrollX","scrollY","parentX","parentY","body","parentRect","getBoundingClientRect","x","y","getPosition","nodeName","push","wordsInThisLine","lineElement","lineDimensions","wordOrElement","next","Math","max","min","isLine","parentData","isChildOfLineNode","_defaults","SplitType","options","static","isSplit","html","innerHTML","constructor","revert","pageXOffset","pageYOffset","scrollTo"],"mappings":"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","file":"5829.936254f124abc52551ef.js","sourcesContent":["/**\n * SplitType\n * https://github.com/lukePeavey/SplitType\n * @version 0.3.3\n * @author Luke Peavey \n */\n\n// Polyfill the following DOM methods that are not supported in IE 11.\n\n(() => {\n function append(...nodes) {\n const length = nodes.length;\n\n for (let i = 0; i < length; i++) {\n const node = nodes[i];\n if (node.nodeType === 1 || node.nodeType === 11) this.appendChild(node);else this.appendChild(document.createTextNode(String(node)));\n }\n }\n\n function replaceChildren(...nodes) {\n while (this.lastChild) {\n this.removeChild(this.lastChild);\n }\n\n if (nodes.length) this.append(...nodes);\n }\n\n function replaceWith(...nodes) {\n const parent = this.parentNode;\n let i = nodes.length;\n if (!parent) return;\n if (!i) parent.removeChild(this);\n\n while (i--) {\n let node = nodes[i];\n\n if (typeof node !== 'object') {\n node = this.ownerDocument.createTextNode(node);\n } else if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n\n if (!i) {\n parent.replaceChild(node, this);\n } else {\n parent.insertBefore(this.previousSibling, node);\n }\n }\n }\n\n if (typeof Element !== 'undefined') {\n if (!Element.prototype.append) {\n Element.prototype.append = append;\n DocumentFragment.prototype.append = append;\n }\n\n if (!Element.prototype.replaceChildren) {\n Element.prototype.replaceChildren = replaceChildren;\n DocumentFragment.prototype.replaceChildren = replaceChildren;\n }\n\n if (!Element.prototype.replaceWith) {\n Element.prototype.replaceWith = replaceWith;\n DocumentFragment.prototype.replaceWith = replaceWith;\n }\n }\n})();\n\n/**\n * Shallow merges the properties of an object with the target object. Only\n * includes properties that exist on the target object. Non-writable properties\n * on the target object will not be over-written.\n *\n * @param {Object} target\n * @param {Object} object\n */\nfunction extend(target, object) {\n return Object.getOwnPropertyNames(Object(target)).reduce((extended, key) => {\n const currentValue = Object.getOwnPropertyDescriptor(Object(target), key);\n const newValue = Object.getOwnPropertyDescriptor(Object(object), key);\n return Object.defineProperty(extended, key, newValue || currentValue);\n }, {});\n}\n\n/**\n * Checks if given value is a string\n *\n * @param {any} value\n * @return {boolean} `true` if `value` is a string, else `false`\n */\nfunction isString(value) {\n return typeof value === 'string';\n}\n\nfunction isArray(value) {\n return Array.isArray(value);\n}\n\n/**\n * Parses user supplied settings objects.\n */\n\nfunction parseSettings(settings = {}) {\n const object = extend(settings); // `split` may be used as an alias for the `types` option\n // Parse the `types` settings into an array of valid split types.\n // If `types` is explicitly set to an empty string or array, text will not be\n // split at all.\n\n let types;\n\n if (object.types !== undefined) {\n types = object.types;\n } else if (object.split !== undefined) {\n types = object.split;\n }\n\n if (types !== undefined) {\n object.types = (isString(types) || isArray(types) ? String(types) : '').split(',').map(type => String(type).trim()).filter(type => /((line)|(word)|(char))/i.test(type));\n } // Support `position: absolute` as an alias for `absolute: true`\n\n\n if (object.absolute || object.position) {\n object.absolute = object.absolute || /absolute/.test(settings.position);\n }\n\n return object;\n}\n\n/**\n * Takes a list of `types` and returns an object\n *\n * @param {string | string[]} value a comma separated list of split types\n * @return {{lines: boolean, words: boolean, chars: boolean}}\n */\n\nfunction parseTypes(value) {\n const types = isString(value) || isArray(value) ? String(value) : '';\n return {\n none: !types,\n lines: /line/i.test(types),\n words: /word/i.test(types),\n chars: /char/i.test(types)\n };\n}\n\n/**\n * Returns true if `value` is a non-null object.\n * @param {any} value\n * @return {boolean}\n */\nfunction isObject(value) {\n return value !== null && typeof value === 'object';\n}\n\n/**\n * Returns true if `input` is one of the following:\n * - `Element`\n * - `Text`\n * - `DocumentFragment`\n */\n\nfunction isNode(input) {\n return isObject(input) && /^(1|3|11)$/.test(input.nodeType);\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n * Original source: Lodash\n *\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3)\n * // => true\n *\n * _.isLength(Number.MIN_VALUE)\n * // => false\n *\n * _.isLength(Infinity)\n * // => false\n *\n * _.isLength('3')\n * // => false\n */\n\nfunction isLength(value) {\n return typeof value === 'number' && value > -1 && value % 1 === 0;\n}\n/**\n * Checks if `value` is an array-like object\n * @param {any} value\n * @return {boolean} true if `value` is array-like`, else `false`\n * @example\n * isArrayLike(new Array())\n * // => true\n *\n * isArrayLike(document.querySelectorAll('div'))\n * // => true\n *\n * isArrayLike(document.getElementsByTagName('div'))\n * // => true\n *\n * isArrayLike(() => {})\n * // => false\n *\n * isArrayLike({foo: 'bar'})\n * // => false\n *\n * * isArrayLike(null)\n * // => false\n */\n\n\nfunction isArrayLike(value) {\n return isObject(value) && isLength(value.length);\n}\n\n/**\n * Coerces `value` to an `Array`.\n *\n * @param {any} value\n * @return {any[]}\n * @example\n * // If `value` is any `Array`, returns original `Array`\n * let arr = [1, 2]\n * toArray(arr)\n * // => arr\n *\n * // If `value` is an `ArrayLike`, its equivalent to `Array.from(value)`\n * let nodeList = document.querySelectorAll('div')\n * toArray(nodeList)\n * // => HTMLElement[] s\n *\n * // If value is falsy, returns empty array\n * toArray(null)\n * // => []\n *\n * // For any other type of value, its equivalent to `Array.of(value)`\n * let element = document.createElement('div')\n * toArray(element)\n * // => [element]\n *\n */\n\nfunction toArray(value) {\n if (isArray(value)) return value;\n if (value == null) return [];\n return isArrayLike(value) ? Array.prototype.slice.call(value) : [value];\n}\n\n/**\n * Processes target elements for the splitType function.\n *\n * @param {any} target Can be one of the following:\n * 1. `string` - A css selector\n * 2. `HTMLElement` - A single element\n * 3. `NodeList` - A nodeList\n * 4. `Element[]` - An array of elements\n * 5. `Array` - An nested array of elements\n * @returns {Element[]} A flat array HTML elements\n * @return A flat array of elements or empty array if no elements are found\n */\n\nfunction getTargetElements(target) {\n let elements = target; // If `target` is a selector string...\n\n if (isString(target)) {\n if (/^(#[a-z]\\w+)$/.test(target.trim())) {\n // If `target` is an ID, use `getElementById`\n elements = document.getElementById(target.trim().slice(1));\n } else {\n // Else use `querySelectorAll`\n elements = document.querySelectorAll(target);\n }\n } // Return a flattened array of elements\n\n\n return toArray(elements).reduce((result, element) => {\n return [...result, ...toArray(element).filter(isNode)];\n }, []);\n}\n\nconst {\n entries,\n keys,\n values\n} = Object;\n\nconst expando = `_splittype`;\nconst cache = {};\nlet uid = 0;\n/**\n * Stores data associated with DOM elements or other objects. This is a\n * simplified version of jQuery's data method.\n *\n * @signature Data(owner)\n * @description Get the data store object for the given owner.\n * @param {Object} owner the object that data will be associated with.\n * @return {Object} the data object for given `owner`. If no data exists\n * for the given object, creates a new data store and returns it.\n *\n * @signature Data(owner, key)\n * @description Get the value\n * @param {Object} owner\n * @param {string} key\n * @return {any} the value of the provided key. If key does not exist, returns\n * undefined.\n *\n * @signature Data(owner, key, value)\n * @description Sets the given key/value pair in data store\n * @param {Object} owner\n * @param {string} key\n * @param {any} value\n */\n\nfunction set(owner, key, value) {\n if (!isObject(owner)) {\n console.warn('[data.set] owner is not an object');\n return null;\n }\n\n const id = owner[expando] || (owner[expando] = ++uid);\n const data = cache[id] || (cache[id] = {});\n\n if (value === undefined) {\n if (!!key && Object.getPrototypeOf(key) === Object.prototype) {\n cache[id] = { ...data,\n ...key\n };\n }\n } else if (key !== undefined) {\n data[key] = value;\n }\n\n return value;\n}\nfunction get(owner, key) {\n const id = isObject(owner) ? owner[expando] : null;\n const data = id && cache[id] || {};\n\n if (key === undefined) {\n return data;\n }\n\n return data[key];\n}\n/**\n * Remove all data associated with the given element\n */\n\nfunction remove(element) {\n const id = element && element[expando];\n\n if (id) {\n delete element[id];\n delete cache[id];\n }\n}\n/**\n * Remove all temporary data from the store.\n */\n\nfunction cleanup() {\n entries(cache).forEach(([id, {\n isRoot,\n isSplit\n }]) => {\n if (!isRoot || !isSplit) {\n cache[id] = null;\n delete cache[id];\n }\n });\n}\n\n/**\n * Splits a string into an array of words.\n *\n * @param {string} string\n * @param {string | RegExp} [separator = ' ']\n * @return {string[]} Array of words\n */\nfunction toWords(value, separator = ' ') {\n const string = value ? String(value) : '';\n return string.trim().replace(/\\s+/g, ' ').split(separator);\n}\n\n/**\n * Based on lodash#split \n * Copyright jQuery Foundation and other contributors \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters &\n * Editors\n */\nconst rsAstralRange = '\\\\ud800-\\\\udfff';\nconst rsComboMarksRange = '\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe23';\nconst rsComboSymbolsRange = '\\\\u20d0-\\\\u20f0';\nconst rsVarRange = '\\\\ufe0e\\\\ufe0f';\n/** Used to compose unicode capture groups. */\n\nconst rsAstral = `[${rsAstralRange}]`;\nconst rsCombo = `[${rsComboMarksRange}${rsComboSymbolsRange}]`;\nconst rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]';\nconst rsModifier = `(?:${rsCombo}|${rsFitz})`;\nconst rsNonAstral = `[^${rsAstralRange}]`;\nconst rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}';\nconst rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]';\nconst rsZWJ = '\\\\u200d';\n/** Used to compose unicode regexes. */\n\nconst reOptMod = `${rsModifier}?`;\nconst rsOptVar = `[${rsVarRange}]?`;\nconst rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*';\nconst rsSeq = rsOptVar + reOptMod + rsOptJoin;\nconst rsSymbol = `(?:${[`${rsNonAstral}${rsCombo}?`, rsCombo, rsRegional, rsSurrPair, rsAstral].join('|')}\n)`;\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n\nconst reUnicode = RegExp(`${rsFitz}(?=${rsFitz})|${rsSymbol}${rsSeq}`, 'g');\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n\nconst unicodeRange = [rsZWJ, rsAstralRange, rsComboMarksRange, rsComboSymbolsRange, rsVarRange];\nconst reHasUnicode = RegExp(`[${unicodeRange.join('')}]`);\n/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n\nfunction asciiToArray(string) {\n return string.split('');\n}\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\n\n\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n\n\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n/**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n\n\nfunction stringToArray(string) {\n return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string);\n}\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values.\n *\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\n\nfunction toString(value) {\n return value == null ? '' : String(value);\n}\n/**\n * Splits `string` into an array of characters. If `separator` is omitted,\n * it behaves likes split.split('').\n *\n * Unlike native string.split(''), it can split strings that contain unicode\n * characters like emojis and symbols.\n *\n * @param {string} [string=''] The string to split.\n * @param {RegExp|string} [separator=''] The separator pattern to split by.\n * @returns {Array} Returns the string segments.\n * @example\n * toChars('foo');\n * // => ['f', 'o', 'o']\n *\n * toChars('foo bar');\n * // => [\"f\", \"o\", \"o\", \" \", \"b\", \"a\", \"r\"]\n *\n * toChars('f😀o');\n * // => ['f', '😀', 'o']\n *\n * toChars('f-😀-o', /-/);\n * // => ['f', '😀', 'o']\n *\n */\n\n\nfunction toChars(string, separator = '') {\n string = toString(string);\n\n if (string && isString(string)) {\n if (!separator && hasUnicode(string)) {\n return stringToArray(string);\n }\n }\n\n return string.split(separator);\n}\n\n/**\n * Create an HTML element with the the given attributes\n *\n * attributes can include standard HTML attribute, as well as the following\n * \"special\" properties:\n * - children: HTMLElement | ArrayLike\n * - textContent: string\n * - innerHTML: string\n *\n * @param {string} name\n * @param {Object} [attributes]\n * @returns {HTMLElement}\n */\n\nfunction createElement(name, attributes) {\n const element = document.createElement(name);\n\n if (!attributes) {\n // When called without the second argument, its just return the result\n // of `document.createElement`\n return element;\n }\n\n Object.keys(attributes).forEach(attribute => {\n const rawValue = attributes[attribute];\n const value = isString(rawValue) ? rawValue.trim() : rawValue; // Ignore attribute if the value is `null` or an empty string\n\n if (value === null || value === '') return;\n\n if (attribute === 'children') {\n // Children can be one or more Elements or DOM strings\n element.append(...toArray(value));\n } else {\n // Handle standard HTML attributes\n element.setAttribute(attribute, value);\n }\n });\n return element;\n}\n\nvar defaults = {\n splitClass: '',\n lineClass: 'line',\n wordClass: 'word',\n charClass: 'char',\n types: ['lines', 'words', 'chars'],\n absolute: false,\n tagName: 'div'\n};\n\n/**\n * Splits the text content of a single TextNode into words and/or characters.\n *\n * This functions gets called for every text node inside the target element. It\n * replaces the text node with a document fragment containing the split text.\n * Returns an array of the split word and character elements from this node.\n *\n * @param {TextNode} textNode\n * @param {Object} settings\n * @return {{words: Element[], chars: Element[]}}\n */\n\nfunction splitWordsAndChars(textNode, settings) {\n settings = extend(defaults, settings); // The split types\n\n const types = parseTypes(settings.types); // the tag name for split text nodes\n\n const TAG_NAME = settings.tagName; // value of the text node\n\n const VALUE = textNode.nodeValue; // `splitText` is a wrapper to hold the HTML structure\n\n const splitText = document.createDocumentFragment(); // Arrays of split word and character elements\n\n let words = [];\n let chars = [];\n\n if (/^\\s/.test(VALUE)) {\n splitText.append(' ');\n } // Create an array of wrapped word elements.\n\n\n words = toWords(VALUE).reduce((result, WORD, idx, arr) => {\n // Let `wordElement` be the wrapped element for the current word\n let wordElement;\n let characterElementsForCurrentWord; // -> If splitting text into characters...\n\n if (types.chars) {\n // Iterate through the characters in the current word\n characterElementsForCurrentWord = toChars(WORD).map(CHAR => {\n const characterElement = createElement(TAG_NAME, {\n class: `${settings.splitClass} ${settings.charClass}`,\n style: 'display: inline-block;',\n children: CHAR\n });\n set(characterElement, 'isChar', true);\n chars = [...chars, characterElement];\n return characterElement;\n });\n } // END IF;\n\n\n if (types.words || types.lines) {\n // -> If Splitting Text Into Words...\n // Create an element to wrap the current word. If we are also\n // splitting text into characters, the word element will contain the\n // wrapped character nodes for this word. If not, it will contain the\n // plain text content (WORD)\n wordElement = createElement(TAG_NAME, {\n class: `${settings.wordClass} ${settings.splitClass}`,\n style: `display: inline-block; ${types.words && settings.absolute ? `position: relative;` : ''}`,\n children: types.chars ? characterElementsForCurrentWord : WORD\n });\n set(wordElement, {\n isWord: true,\n isWordStart: true,\n isWordEnd: true\n });\n splitText.appendChild(wordElement);\n } else {\n // -> If NOT splitting into words OR lines...\n // Append the characters elements directly to splitText.\n characterElementsForCurrentWord.forEach(characterElement => {\n splitText.appendChild(characterElement);\n });\n }\n\n if (idx < arr.length - 1) {\n // Add a space after the word.\n splitText.append(' ');\n } // If not splitting text into words, we return an empty array\n\n\n return types.words ? result.concat(wordElement) : result;\n }, []); // END LOOP;\n // Add a trailing white space to maintain word spacing\n\n if (/\\s$/.test(VALUE)) {\n splitText.append(' ');\n }\n\n textNode.replaceWith(splitText);\n return {\n words,\n chars\n };\n}\n\n/**\n * Splits the text content of a target element into words and/or characters.\n * The function is recursive, it will also split the text content of any child\n * elements into words/characters, while preserving the nested elements.\n *\n * @param {Node} node an HTML Element or Text Node\n * @param {Object} setting splitType settings\n */\n\nfunction split(node, settings) {\n const type = node.nodeType; // Arrays of split words and characters\n\n const wordsAndChars = {\n words: [],\n chars: []\n }; // Only proceed if `node` is an `Element`, `Fragment`, or `Text`\n\n if (!/(1|3|11)/.test(type)) {\n return wordsAndChars;\n } // A) IF `node` is TextNode that contains characters other than white space...\n // Split the text content of the node into words and/or characters\n // return an object containing the split word and character elements\n\n\n if (type === 3 && /\\S/.test(node.nodeValue)) {\n return splitWordsAndChars(node, settings);\n } // B) ELSE `node` is an 'Element'\n // Iterate through its child nodes, calling the `split` function\n // recursively for each child node.\n\n\n const childNodes = toArray(node.childNodes);\n\n if (childNodes.length) {\n set(node, 'isSplit', true); // we need to set a few styles on nested html elements\n\n if (!get(node).isRoot) {\n node.style.display = 'inline-block';\n node.style.position = 'relative'; // To maintain original spacing around nested elements when we are\n // splitting text into lines, we need to check if the element should\n // have a space before and after, and store that value for later.\n // Note: this was necessary to maintain the correct spacing when nested\n // elements do not align with word boundaries. For example, a nested\n // element only wraps part of a word.\n\n const nextSibling = node.nextSibling;\n const prevSibling = node.previousSibling;\n const text = node.textContent || '';\n const textAfter = nextSibling ? nextSibling.textContent : ' ';\n const textBefore = prevSibling ? prevSibling.textContent : ' ';\n set(node, {\n isWordEnd: /\\s$/.test(text) || /^\\s/.test(textAfter),\n isWordStart: /^\\s/.test(text) || /\\s$/.test(textBefore)\n });\n }\n } // Iterate through child nodes, calling `split` recursively\n // Returns an object containing all split words and chars\n\n\n return childNodes.reduce((result, child) => {\n const {\n words,\n chars\n } = split(child, settings);\n return {\n words: [...result.words, ...words],\n chars: [...result.chars, ...chars]\n };\n }, wordsAndChars);\n}\n\n/**\n * Gets the height and position of an element relative to offset parent.\n * Should be equivalent to offsetTop and offsetHeight, but with sub-pixel\n * precision.\n *\n * TODO needs work\n */\nfunction getPosition(node, isWord, settings, scrollPos) {\n if (!settings.absolute) {\n return {\n top: isWord ? node.offsetTop : null\n };\n }\n\n const parent = node.offsetParent;\n const [scrollX, scrollY] = scrollPos;\n let parentX = 0;\n let parentY = 0;\n\n if (parent && parent !== document.body) {\n const parentRect = parent.getBoundingClientRect();\n parentX = parentRect.x + scrollX;\n parentY = parentRect.y + scrollY;\n }\n\n const {\n width,\n height,\n x,\n y\n } = node.getBoundingClientRect();\n const top = y + scrollY - parentY;\n const left = x + scrollX - parentX;\n return {\n width,\n height,\n top,\n left\n };\n}\n\n/**\n * Recursively \"un-splits\" text into words.\n * This is used when splitting text into lines but not words.\n * We initially split the text into words so we can maintain the correct line\n * breaks. Once text has been split into lines, we \"un-split\" the words...\n * @param {Element}\n * @return {void}\n */\n\nfunction unSplitWords(element) {\n if (!get(element).isWord) {\n toArray(element.children).forEach(child => unSplitWords(child));\n } else {\n remove(element);\n element.replaceWith(...element.childNodes);\n }\n}\n\nconst createFragment = () => document.createDocumentFragment();\n\nfunction repositionAfterSplit(element, settings, scrollPos) {\n const types = parseTypes(settings.types);\n const TAG_NAME = settings.tagName;\n const nodes = element.getElementsByTagName('*');\n const wordsInEachLine = [];\n let wordsInCurrentLine = [];\n let lineOffsetY = null;\n let elementHeight;\n let elementWidth;\n let contentBox;\n let lines = [];\n /**------------------------------------------------\n ** GET STYLES AND POSITIONS\n **-----------------------------------------------*/\n // There is no built-in way to detect natural line breaks in text (when a\n // block of text wraps to fit its container). To split text into lines, we\n // have to detect line breaks by checking the top offset of words. This is\n // why text was split into words first. To apply absolute\n // positioning, its also necessary to record the size and position of every\n // split node (lines, words, characters).\n // To consolidate DOM getting/settings, this is all done at the same time,\n // before actually splitting text into lines, which involves restructuring\n // the DOM again.\n // Cache the element's parent and next sibling (for DOM removal).\n\n const parent = element.parentElement;\n const nextSibling = element.nextElementSibling; // a wrapper for the new HTML structure\n\n const splitText = createFragment(); // get the computed style object for the element\n\n const cs = window.getComputedStyle(element);\n const align = cs.textAlign;\n const fontSize = parseFloat(cs.fontSize);\n const lineThreshold = fontSize * 0.2; // IF using absolute position...\n\n if (settings.absolute) {\n // Let contentBox be an object containing the width and offset position of\n // the element's content box (the area inside padding box). This is needed\n // (for absolute positioning) to set the width and position of line\n // elements, which have not been created yet.\n contentBox = {\n left: element.offsetLeft,\n top: element.offsetTop,\n width: element.offsetWidth\n }; // Let elementWidth and elementHeight be the actual width/height of the\n // element. Also check if the element has inline height or width styles\n // already set. If it does, cache those values for later.\n\n elementWidth = element.offsetWidth;\n elementHeight = element.offsetHeight; // Store the original inline height and width of the element\n\n set(element, {\n cssWidth: element.style.width,\n cssHeight: element.style.height\n });\n } // Iterate over every node in the target element\n\n\n toArray(nodes).forEach(node => {\n // node is a word element or custom html element\n const isWordLike = node.parentElement === element; // TODO needs work\n // Get te size and position of split text nodes\n\n const {\n width,\n height,\n top,\n left\n } = getPosition(node, isWordLike, settings, scrollPos); // If element is a `
` tag return here\n\n if (/^br$/i.test(node.nodeName)) return;\n\n if (types.lines && isWordLike) {\n // We compare the top offset of the current word to the top offset of\n // previous words on the current line. If the difference is greater than\n // our defined threshold (20%), we assume this word is on a new line.\n if (lineOffsetY === null || top - lineOffsetY >= lineThreshold) {\n lineOffsetY = top;\n wordsInEachLine.push(wordsInCurrentLine = []);\n } // Add the current word node to the line array\n\n\n wordsInCurrentLine.push(node);\n } // END IF\n\n\n if (settings.absolute) {\n // Store the size and position split text nodes\n set(node, {\n top,\n left,\n width,\n height\n });\n }\n }); // END LOOP\n // Remove the element from the DOM\n\n if (parent) {\n parent.removeChild(element);\n }\n /**------------------------------------------------\n ** SPLIT LINES\n **-----------------------------------------------*/\n\n\n if (types.lines) {\n // Iterate over lines of text (see 11 b)\n // Let `line` be the array of words in the current line.\n // Return an array of the wrapped line elements (lineElements)\n lines = wordsInEachLine.map(wordsInThisLine => {\n // Create an element to wrap the current line.\n const lineElement = createElement(TAG_NAME, {\n class: `${settings.splitClass} ${settings.lineClass}`,\n style: `display: block; text-align: ${align}; width: 100%;`\n });\n set(lineElement, 'isLine', true);\n const lineDimensions = {\n height: 0,\n top: 1e4\n }; // Append the `lineElement` to `container`\n\n splitText.appendChild(lineElement); // Iterate over the word-level elements in the current line.\n // Note: wordOrElement can either be a word node or nested element\n\n wordsInThisLine.forEach((wordOrElement, idx, arr) => {\n const {\n isWordEnd,\n top,\n height\n } = get(wordOrElement);\n const next = arr[idx + 1]; // Determine line height / y-position\n // we use the height and offsetTop of the words which we already\n // recorded. Because custom nested elements could have their own\n // styles, the words on a line may not all be the same height or\n // y position. So we take the greatest height / y - offset of the\n // words on this line.\n\n lineDimensions.height = Math.max(lineDimensions.height, height);\n lineDimensions.top = Math.min(lineDimensions.top, top); // append the current word/element\n\n lineElement.appendChild(wordOrElement); // Determine if there should space after the current element...\n // If this is not the last word on the current line.\n // TODO - logic for handing spacing can be improved\n\n if (isWordEnd && get(next).isWordStart) {\n lineElement.append(' ');\n }\n }); // END LOOP\n\n if (settings.absolute) {\n set(lineElement, {\n height: lineDimensions.height,\n top: lineDimensions.top\n });\n }\n\n return lineElement;\n }); // END LOOP\n\n if (!types.words) {\n unSplitWords(splitText);\n } // 10. Insert the new container\n\n\n element.replaceChildren(splitText);\n }\n /**------------------------------------------------\n ** SET ABSOLUTE POSITION\n **-----------------------------------------------*/\n // Apply absolute positioning to all child elements of the target element.\n // This includes split lines, words, chars, and custom HTML elements that were\n // included by the user. The size and position of child elements has already\n // been recorded before splitting text into lines.\n\n\n if (settings.absolute) {\n // Set the width/height of the parent element so it does not collapse\n // when its children are set to absolute position.\n element.style.width = `${element.style.width || elementWidth}px`;\n element.style.height = `${elementHeight}px`; // Iterate over all child elements\n\n toArray(nodes).forEach(node => {\n const {\n isLine,\n top,\n left,\n width,\n height\n } = get(node);\n const parentData = get(node.parentElement);\n const isChildOfLineNode = !isLine && parentData.isLine; // Set the top position of the current node.\n // -> If `node` a line element, we use the top offset of its first child\n // -> If `node` the child of line element, then its top offset is zero\n\n node.style.top = `${isChildOfLineNode ? top - parentData.top : top}px`; // Set the left position of the current node.\n // -> IF `node` is a line element, this is equal to the position left of\n // the content box of the parent element\n // -> IF `node` is the child of a line element, the value has to adjusted\n // so its relative to the line element\n\n node.style.left = isLine ? `${contentBox.left}px` : `${left - (isChildOfLineNode ? contentBox.left : 0)}px`; // Set the height of the current node to the cached value.\n\n node.style.height = `${height}px`; // Set the width of the current node.\n // If its a line element, width is equal to the width of the contentBox.\n\n node.style.width = isLine ? `${contentBox.width}px` : `${width}px`; // Finally, set the node's position to absolute.\n\n node.style.position = 'absolute';\n });\n } // end if;\n // 14. Re-attach the element to the DOM\n\n\n if (parent) {\n if (nextSibling) parent.insertBefore(element, nextSibling);else parent.appendChild(element);\n }\n\n return lines;\n}\n\nlet _defaults = extend(defaults, {});\n\nclass SplitType {\n /**\n * The internal data store\n */\n static get data() {\n return cache;\n }\n /**\n * The default settings for all splitType instances\n * @static\n */\n\n\n static get defaults() {\n return _defaults;\n }\n /**\n * Sets the default settings for all SplitType instances.\n *\n * Setting `SplitType.defaults` to an object will merge that object with the\n * existing defaults.\n *\n * @param {Object} settings an object containing the settings to override\n * @deprecated\n * @static\n * @example\n * SplitType.defaults = { \"position\": \"absolute\" }\n */\n\n\n static set defaults(options) {\n _defaults = extend(_defaults, parseSettings(options));\n }\n /**\n * Sets the default settings for all SplitType instances.\n * The provided object will be merged with the existing defaults objects.\n *\n * @param {Object} settings an object containing the settings to override\n * @returns {Object} the new default settings\n * @public\n * @static\n * @example\n * SplitType.setDefaults({ \"position\": \"absolute\" })\n */\n\n\n static setDefaults(options) {\n _defaults = extend(_defaults, parseSettings(options));\n return defaults;\n }\n /**\n * Revert target elements to their original html content\n * Has no effect on that\n *\n * @param {any} elements The target elements to revert. One of:\n * - {string} A css selector\n * - {HTMLElement} A single element\n * - {NodeList} A NodeList or collection\n * - {HTMLElement[]} An array of Elements\n * - {Array} A nested array of elements\n * @static\n */\n\n\n static revert(elements) {\n getTargetElements(elements).forEach(element => {\n const {\n isSplit,\n html,\n cssWidth,\n cssHeight\n } = get(element);\n\n if (isSplit) {\n element.innerHTML = html;\n element.style.width = cssWidth || '';\n element.style.height = cssHeight || '';\n remove(element);\n }\n });\n }\n /**\n * Creates a new SplitType instance\n * This static method provides a way to create a `SplitType` instance without\n * using the `new` keyword.\n *\n * @param {any} target The target elements to split. One of:\n * - {string} A css selector\n * - {HTMLElement} A single element\n * - {NodeList} A NodeList or collection\n * - {HTMLElement[]} An array of Elements\n * - {Array} A nested array of elements\n * @param {Object} [options] Settings for the SplitType instance\n * @return {SplitType} the SplitType instance\n * @static\n */\n\n\n static create(target, options) {\n return new SplitType(target, options);\n }\n /**\n * Creates a new `SplitType` instance\n *\n * @param {any} elements The target elements to split. One of:\n * - {string} A css selector\n * - {HTMLElement} A single element\n * - {NodeList} A NodeList or collection\n * - {HTMLElement[]} An array of Elements\n * - {Array} A nested array of elements\n * @param {Object} [options] Settings for the SplitType instance\n */\n\n\n constructor(elements, options) {\n this.isSplit = false;\n this.settings = extend(_defaults, parseSettings(options));\n this.elements = getTargetElements(elements); // Start the split process\n\n this.split();\n }\n /**\n * Splits the text in all target elements. This method is called\n * automatically when a new SplitType instance is created. It can also be\n * called manually to re-split text with new options.\n * @param {Object} options\n * @public\n */\n\n\n split(options) {\n // Revert target elements (if they are already split)\n // Note: revert was already called once in the constructor. However, we\n // need to call it again here so text is reverted when the user manually\n // calls the `split` method to re-split text.\n this.revert(); // Store the original html content of each target element\n\n this.elements.forEach(element => {\n set(element, 'html', element.innerHTML);\n }); // Create arrays to hold the split lines, words, and characters\n\n this.lines = [];\n this.words = [];\n this.chars = []; // cache vertical scroll position before splitting\n\n const scrollPos = [window.pageXOffset, window.pageYOffset]; // If new options were passed into the `split()` method, update settings\n\n if (options !== undefined) {\n this.settings = extend(this.settings, parseSettings(options));\n }\n\n const types = parseTypes(this.settings.types); // If the `types` option is set to an empty array, text will not be split.\n // @example new SplitType('#target', { types: [] })\n\n if (types.none) {\n return;\n } // Split text in each target element\n\n\n this.elements.forEach(element => {\n // Add the split text nodes from this element to the arrays of all split\n // text nodes for this instance.\n set(element, 'isRoot', true);\n const {\n words,\n chars\n } = split(element, this.settings);\n this.words = [...this.words, ...words];\n this.chars = [...this.chars, ...chars];\n });\n this.elements.forEach(element => {\n if (types.lines || this.settings.absolute) {\n const lines = repositionAfterSplit(element, this.settings, scrollPos);\n this.lines = [...this.lines, ...lines];\n }\n }); // Set isSplit to true for the SplitType instance\n\n this.isSplit = true; // Set scroll position to cached value.\n\n window.scrollTo(scrollPos[0], scrollPos[1]); // Clean up stored data\n\n cleanup();\n }\n /**\n * Reverts target element(s) back to their original html content\n * Deletes all stored data associated with the target elements\n * Resets the properties on the splitType instance\n *\n * @public\n */\n\n\n revert() {\n if (this.isSplit) {\n // Reset instance properties if necessary\n this.lines = null;\n this.words = null;\n this.chars = null;\n this.isSplit = false;\n }\n\n SplitType.revert(this.elements);\n }\n\n}\n\nexport { SplitType as default };\n"],"sourceRoot":""}