{
"version": 3,
"sources": ["../themes/workstringsinternational.com/js/$.js", "../themes/workstringsinternational.com/modules/site-header/default/index.js", "../themes/workstringsinternational.com/modules/two-column/default/index.js", "../themes/workstringsinternational.com/modules/cta/2-col/index.js", "../themes/workstringsinternational.com/modules/page-header/home/index.js", "../themes/workstringsinternational.com/modules/page-list/filter-grid/index.js", "../themes/workstringsinternational.com/modules/map/default/styles.json", "../themes/workstringsinternational.com/modules/map/default/index.js", "../node_modules/simple-datatables/src/helpers.ts", "../node_modules/simple-datatables/node_modules/diff-dom/dist/module.js", "../node_modules/simple-datatables/src/virtual_dom.ts", "../node_modules/simple-datatables/node_modules/dayjs/dayjs.min.js", "../node_modules/simple-datatables/node_modules/dayjs/plugin/customParseFormat.js", "../node_modules/simple-datatables/src/date.ts", "../node_modules/simple-datatables/src/read_data.ts", "../node_modules/simple-datatables/src/rows.ts", "../node_modules/simple-datatables/src/columns.ts", "../node_modules/simple-datatables/src/column_settings.ts", "../node_modules/simple-datatables/src/templates.ts", "../node_modules/simple-datatables/src/config.ts", "../node_modules/simple-datatables/src/virtual_pager_dom.ts", "../node_modules/simple-datatables/src/datatable.ts", "../node_modules/simple-datatables/src/convert/csv.ts", "../node_modules/simple-datatables/src/convert/json.ts", "../node_modules/simple-datatables/src/export/csv.ts", "../node_modules/simple-datatables/src/export/json.ts", "../node_modules/simple-datatables/src/export/sql.ts", "../node_modules/simple-datatables/src/export/txt.ts", "../node_modules/simple-datatables/src/editing/config.ts", "../node_modules/simple-datatables/src/editing/editor.ts", "../node_modules/simple-datatables/src/column_filter/config.ts", "../node_modules/simple-datatables/src/column_filter/column_filter.ts", "../themes/workstringsinternational.com/modules/table/spec-sheets/columns.json", "../node_modules/@brandextract-dev/workstrings-data/lib/pdf-constants.js", "../node_modules/big.js/big.mjs", "../node_modules/@brandextract-dev/workstrings-data/lib/normalize.js", "../node_modules/fraction.js/dist/fraction.mjs", "../themes/workstringsinternational.com/modules/table/spec-sheets/index.js", "../themes/workstringsinternational.com/modules/contact-form/default/index.js", "../node_modules/gsap/gsap-core.js", "../node_modules/gsap/CSSPlugin.js", "../node_modules/gsap/index.js", "../themes/workstringsinternational.com/modules/timeline/default/index.js", "../themes/workstringsinternational.com/modules/article/default/index.js", "../themes/workstringsinternational.com/modules/search/Google-CSE/index.js", "../node_modules/gsap/Observer.js", "../node_modules/gsap/ScrollTrigger.js", "../themes/workstringsinternational.com/js/observers.js", "../themes/workstringsinternational.com/js/dialog.js", "../themes/workstringsinternational.com/js/index.js"],
"sourcesContent": ["/**\n * Queries for a single element with selector\n * @param {string} selector\n * @param {Document|Element} [parent=document]\n * @returns {Element}\n */\nglobalThis.$ = (selector, parent = document) => parent.querySelector(selector);\n\n/**\n * Queries for a node list with selector\n * @param {string} selector\n * @param {Document|Element} [parent=document]\n * @returns {NodeList}\n */\nglobalThis.$$ = (selector, parent = document) =>\n parent.querySelectorAll(selector);\n", "const $ = (selector, parent = document) => parent.querySelector(selector);\nconst $$ = (selector, parent = document) => parent.querySelectorAll(selector);\n\nconst mobileMenu = $(\"header[role='banner'].site-header\");\n\nfunction throttle(fn, wait) {\n let time = Date.now();\n return function() {\n if ((time + wait - Date.now()) < 0) {\n fn();\n time = Date.now();\n }\n }\n}\n\nfunction toggleMobileMenu() {\n const button = $(`.site-header [aria-controls=\"primary-nav\"]`);\n const state = button.getAttribute(\"aria-expanded\");\n const isOpen = state === \"true\";\n const mobileMenu = $(\"header[role='banner'].site-header\");\n\n button.setAttribute(\"aria-expanded\", isOpen ? \"false\" : \"true\");\n button.innerText = isOpen ? \"Menu\" : \"Close\";\n mobileMenu.classList.toggle(\"menu-open\");\n $(\"body\").classList.toggle(\"overflow-hidden\");\n}\n\nfunction openSubnav(parent) {\n const button = $(\"button\", parent);\n\n parent?.classList.add(\"open\");\n button?.setAttribute(`aria-expanded`, `true`);\n}\n\nfunction closeSubnav(parent) {\n const button = $(\"button\", parent);\n\n parent?.classList.remove(\"open\");\n button?.setAttribute(`aria-expanded`, `false`);\n}\n\nfunction closeSubnavs() {\n const openMenus = $$(\".site-header .isParent.open, .site-header .isGrandParent.open\");\n openMenus.forEach(function(menu) {\n closeSubnav(menu);\n })\n}\n\n// $(\".search-toggle\").addEventListener(\"click\", function(event) {\n// $(\"header nav[aria-label='Utility'] form[role='search'] input.search-field\").focus();\n// });\n\ndocument.addEventListener(\"click\", function(event) {\n const button = event.target.closest(`.site-header [aria-controls=\"primary-nav\"]`);\n if (!button) {\n return;\n }\n\n toggleMobileMenu();\n});\n\ndocument.addEventListener('touchend', function (event) {\n let closest = event.target.closest(\".site-header:not(.menu-open) .isParent > a, .site-header:not(.menu-open) .isGrandParent > a\");\n if ($(\".site-header.menu-open\")) {\n return;\n }\n \n if (closest) {\n let parent = closest.parentNode;\n if (parent.classList.contains(\"open\")) return;\n closeSubnavs();\n openSubnav(parent);\n } else {\n const inMenu = event.target.closest(\"li.open\");\n if (!inMenu) {\n closeSubnavs();\n }\n return;\n }\n event.preventDefault();\n}, false);\n\ndocument.addEventListener('mouseover', function (event) {\n let closest = event.target.closest(\".site-header:not(.menu-open) nav#primary-nav > ul > .isParent, .site-header:not(.menu-open) nav#primary-nav > ul > .isGrandParent\");\n if (!closest) return;\n openSubnav(closest);\n}, false);\n\ndocument.addEventListener('mouseout', function (event) {\n let closest = event.target.closest(\".site-header:not(.menu-open) nav#primary-nav > ul > .isParent, .site-header:not(.menu-open) nav#primary-nav > ul > .isGrandParent\");\n if (!closest) return;\n closeSubnav(closest);\n}, false);\n\ndocument.addEventListener('click', function (event) {\n let closest = event.target.closest(\".site-header:not(.menu-open) #primary-nav a + button\");\n if (!closest) return;\n\n let $toggle = closest;\n let $navItem = $toggle.closest(`li`);\n let $otherNavItems = Array.prototype.filter.call($navItem.parentNode.children, function(child){\n return child !== $navItem;\n });\n\n $otherNavItems.forEach(item => {\n closeSubnav(item);\n })\n\n if ($navItem.classList.contains(\"open\")) {\n closeSubnav($navItem);\n } else {\n openSubnav($navItem);\n }\n}, false);\n\ndocument.addEventListener('click', function (event) {\n const targets = `\n .site-header.menu-open #primary-nav > ul > .isParent > a,\n .site-header.menu-open #primary-nav > ul > .isParent > button,\n .site-header.menu-open #primary-nav > ul > .isGrandParent > a,\n .site-header.menu-open #primary-nav > ul > .isGrandParent > button\n `\n const closest = event.target.closest(targets);\n if (!closest) return;\n\n const $navItem = closest.parentNode;\n let siblings = Array.prototype.filter.call($navItem.parentNode.children, function(child){\n return child !== $navItem;\n });\n\n event.preventDefault();\n\n if ($navItem.classList.contains(`open`)) {\n closeSubnav($navItem);\n $(\".site-header\").classList.remove(\"submenu-open\");\n } else {\n openSubnav($navItem);\n siblings.forEach(sibling => {\n closeSubnav(sibling);\n })\n $(\".site-header\").classList.add(\"submenu-open\");\n }\n}, false);\n\n// header class on hover\nconst header = document.querySelector('header.site-header');\n\nheader.addEventListener('mouseover', () => {\n header.classList.add('hovered');\n});\nheader.addEventListener('mouseout', () => {\n header.classList.remove('hovered');\n});\n\nlet lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;\n\nlet scrollCallback = function(){\n let scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n let diff = Math.abs(lastScrollTop - scrollTop);\n\n if (!header.classList.contains(\"menu-open\")) {\n if (scrollTop > lastScrollTop){\n if (header.classList.contains(\"unfold\") && diff > 10) {\n header.classList.remove(\"unfold\");\n }\n } else {\n if (!header.classList.contains(\"unfold\") && diff > 10 && document.documentElement.scrollTop > 500) {\n const headerHeight = header.offsetHeight;\n header.classList.add(\"unfold\");\n } else if (header.classList.contains(\"unfold\") && document.documentElement.scrollTop <= 500) {\n header.classList.remove(\"unfold\");\n }\n }\n }\n\n if (diff > 10) {\n lastScrollTop = scrollTop<= 0 ? 0 : scrollTop; // For Mobile or negative scrolling\n }\n}\n\nwindow.addEventListener(\"scroll\", throttle(scrollCallback, 25) , false);", "const $ = (selector, parent = document) => parent.querySelector(selector);\nconst $$ = (selector, parent = document) => parent.querySelectorAll(selector);\n\nconst columnSections = $$(\".two-column-default\");\n\ncolumnSections.forEach(function(section) {\n const columns = $$(\".column:nth-child(even)\", section);\n\n columns.forEach(function(column) {\n if ($(\"p:first-child:last-child img:first-child:last-child\", column)) {\n const previousSibling = column.previousElementSibling;\n const previousPosition = getComputedStyle(previousSibling).getPropertyValue(\"--position\");\n const currentPosition = getComputedStyle(column).getPropertyValue(\"--position\");\n\n column.style.setProperty(\"--mobile-position\", previousPosition);\n previousSibling.style.setProperty(\"--mobile-position\", currentPosition);\n previousSibling.classList.add(\"flipped\");\n }\n });\n});", "const $ = (selector, parent = document) => parent.querySelector(selector);\nconst $$ = (selector, parent = document) => parent.querySelectorAll(selector);\n\nconst observer = new IntersectionObserver(entries => {\n entries.forEach(entry => {\n if (entry.intersectionRatio > 0) {\n entry.target.classList.add('animate');\n }\n else {\n entry.target.classList.remove('animate');\n }\n })\n})\nconst boxElList = $$(\".cta-2-col\");\nboxElList.forEach((el) => {\n observer.observe(el);\n})", "const $ = (selector, parent = document) => parent.querySelector(selector);\nconst $$ = (selector, parent = document) => parent.querySelectorAll(selector);\n\nconst imageSwapper = $(\".page-header-home .image-swapper\");\n\nif (imageSwapper) {\n const items = $$(\"li\", imageSwapper);\n let currentItem = 0;\n\n function swapImage() {\n items[currentItem].classList.remove(\"active\");\n currentItem = (currentItem + 1) % items.length;\n items[currentItem].classList.add(\"active\");\n }\n\n setInterval(swapImage, 5000);\n}", "const $ = (selector, parent = document) => parent.querySelector(selector);\nconst $$ = (selector, parent = document) => parent.querySelectorAll(selector);\n\nconst itemsPerPage = 6;\nlet currentPage = 1;\n\nconst pagination = $(\".pagination\");\n\n$$(\".filter-grid\").forEach(function(filterGrid) {\n const filters = $(\".filters\", filterGrid);\n const items = $$(\"ul.grid li\", filterGrid);\n const grid = $(\"ul.grid\", filterGrid);\n \n\n if (filters) {\n const categories = filters.dataset.categories.split(\",\");\n\n categories.forEach(function(category) {\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.type = \"radio\";\n input.classList.add(\"sr-only\");\n input.name = \"category\";\n input.value = category;\n const span = document.createElement(\"span\");\n span.textContent = category;\n label.appendChild(input);\n label.appendChild(span);\n filters.appendChild(label);\n });\n \n const filterInputs = $$(\"input\", filters);\n filterInputs.forEach(function(input) {\n input.addEventListener(\"change\", function() {\n currentPage = 1;\n const category = this.value;\n items.forEach(function(item) {\n if (category === \"all\") {\n item.classList.remove(\"filtered\");\n } else if (item.dataset.category === category) {\n item.classList.remove(\"filtered\");\n } else {\n item.classList.add(\"filtered\");\n }\n });\n \n $$(\"li:not(.filtered)\", grid).forEach(function(item, index) {\n if (index >= itemsPerPage) {\n item.classList.add(\"hidden\");\n } else {\n item.classList.remove(\"hidden\");\n } \n });\n \n initLoadMore();\n initPagination();\n });\n });\n }\n});\n\nfunction initLoadMore() {\n $$(\".grid-load-more\").forEach(function(loadMoreSection) {\n const hiddenItems = $$(\"li.hidden:not(.filtered)\", loadMoreSection);\n const loadMoreButton = $(\".load-more\", loadMoreSection);\n\n if (!loadMoreButton) {\n return;\n }\n\n if (hiddenItems.length > 0) {\n loadMoreButton.classList.remove(\"hidden\");\n } else {\n loadMoreButton.classList.add(\"hidden\");\n }\n });\n}\n\nfunction initPagination() {\n const pagination = $(\".pagination\");\n const paginationList = $(\".pagination ul\");\n if (!pagination) {\n return;\n }\n\n const itemsNotFiltered = $$(\".grid-load-more .grid li:not(.filtered)\");\n\n if (itemsNotFiltered.length > itemsPerPage) {\n paginationList.innerHTML = \"\";\n\n const pages = Math.floor(itemsNotFiltered.length / itemsPerPage);\n \n if (pages === 1) {\n pagination.classList.add(\"invisible\");\n pagination.classList.add(\"hidden\");\n return;\n }\n\n const previous = document.createElement(\"li\");\n previous.classList.add(\"previous\");\n previous.innerHTML = ``;\n\n //create next button item\n const next = document.createElement(\"li\");\n next.classList.add(\"next\");\n next.innerHTML = ``;\n\n const createPageButton = (pageNumber) => {\n const page = document.createElement(\"li\");\n if (currentPage === pageNumber) {\n page.classList.add(\"active\");\n }\n page.innerHTML = ``;\n return page;\n };\n\n const createEllipsis = () => {\n const ellipsis = document.createElement(\"li\");\n ellipsis.classList.add(\"ellipsis\");\n ellipsis.innerHTML = `...`;\n return ellipsis;\n };\n\n const renderPagination = (currentPage) => {\n paginationList.innerHTML = \"\";\n paginationList.appendChild(previous);\n\n if (pages <= 5) {\n for (let i = 1; i <= pages; i++) {\n paginationList.appendChild(createPageButton(i));\n }\n } else {\n if (currentPage > 4) {\n paginationList.appendChild(createPageButton(1));\n paginationList.appendChild(createPageButton(2));\n paginationList.appendChild(createEllipsis());\n } else {\n for (let i = 1; i <= currentPage - 2; i++) {\n paginationList.appendChild(createPageButton(i));\n }\n }\n\n let startPage = Math.max(1, currentPage - 1);\n let endPage = Math.min(pages, currentPage + 1);\n\n for (let i = startPage; i <= endPage; i++) {\n paginationList.appendChild(createPageButton(i));\n }\n\n if (currentPage < pages - 3) {\n paginationList.appendChild(createEllipsis());\n paginationList.appendChild(createPageButton(pages-1));\n paginationList.appendChild(createPageButton(pages));\n } else if (currentPage + 2 <= pages) {\n for (let i = currentPage + 2; i <= pages; i++) {\n paginationList.appendChild(createPageButton(i));\n }\n }\n }\n\n paginationList.appendChild(next);\n };\n\n renderPagination(currentPage);\n pagination.classList.remove(\"invisible\");\n pagination.classList.remove(\"hidden\");\n }\n}\n\n$(\".grid-load-more .load-more\")?.addEventListener(\"click\", function() {\n const loadMoreSection = this.closest(\".grid-load-more\");\n const hiddenItems = $$(\"li.hidden:not(.filtered)\", loadMoreSection);\n const loadMoreButton = $(\".load-more\", loadMoreSection);\n\n hiddenItems.forEach(function(item, index) {\n if (index < itemsPerPage) {\n item.classList.remove(\"hidden\");\n }\n });\n\n if (hiddenItems.length <= itemsPerPage) {\n loadMoreButton.classList.add(\"hidden\");\n }\n});\n\n\nif (pagination) {\n document.addEventListener(\"click\", function(event) {\n const closest = event.target.closest(\".pagination button\");\n if (!closest) {\n return;\n }\n\n const itemsNotFiltered = $$(\".grid-load-more li:not(.filtered)\");\n const pages = Math.floor(itemsNotFiltered.length / itemsPerPage);\n const page = closest.textContent;\n\n if (page.indexOf(\"<\") > -1) {\n currentPage = Math.max(1, currentPage - 1);\n } else if (page.indexOf(\">\") > -1) {\n currentPage = Math.min(pages, currentPage + 1);\n } else {\n currentPage = parseInt(page);\n }\n\n itemsNotFiltered.forEach(function(item, index) {\n if (index < itemsPerPage * (currentPage - 1) || index >= itemsPerPage * currentPage) {\n item.classList.add(\"hidden\");\n } else {\n item.classList.remove(\"hidden\");\n }\n });\n\n //scroll to section\n const section = $(\".grid-load-more\");\n const offset = section.getBoundingClientRect().top + window.scrollY - 100;\n window.scrollTo({\n top: offset,\n behavior: \"smooth\"\n });\n initPagination();\n });\n}\n\n\ninitLoadMore();\ninitPagination();", "[\n {\n \"featureType\": \"landscape\",\n \"elementType\": \"labels\",\n \"stylers\": [\n {\n \"visibility\": \"off\"\n }\n ]\n },\n {\n \"featureType\": \"transit\",\n \"elementType\": \"labels\",\n \"stylers\": [\n {\n \"visibility\": \"off\"\n }\n ]\n },\n {\n \"featureType\": \"poi\",\n \"elementType\": \"labels\",\n \"stylers\": [\n {\n \"visibility\": \"off\"\n }\n ]\n },\n {\n \"featureType\": \"water\",\n \"elementType\": \"labels\",\n \"stylers\": [\n {\n \"visibility\": \"off\"\n }\n ]\n },\n {\n \"featureType\": \"road\",\n \"elementType\": \"labels.icon\",\n \"stylers\": [\n {\n \"visibility\": \"off\"\n }\n ]\n },\n {\n \"stylers\": [\n {\n \"hue\": \"#00aaff\"\n },\n {\n \"saturation\": -100\n },\n {\n \"gamma\": 2.15\n },\n {\n \"lightness\": 12\n }\n ]\n },\n {\n \"featureType\": \"road\",\n \"elementType\": \"labels.text.fill\",\n \"stylers\": [\n {\n \"visibility\": \"on\"\n },\n {\n \"lightness\": 24\n }\n ]\n },\n {\n \"featureType\": \"road\",\n \"elementType\": \"geometry\",\n \"stylers\": [\n {\n \"lightness\": 57\n }\n ]\n }\n]\n", "import styles from \"./styles.json\";\n\nconst GOOGLE_MAPS_API_KEY = \"AIzaSyCu0RFsEPzifkgirE_Ge5aoRr2tfQHknY0\";\n\nclass ClusterMap {\n static init(maps = document.querySelectorAll(\"gmp-map\")) {\n maps.forEach((mapElement) => new ClusterMap(mapElement));\n }\n\n constructor(mapElement) {\n this.element = mapElement;\n const { innerMap: map } = mapElement;\n const styledMapType = new google.maps.StyledMapType(styles);\n map.mapTypes.set(\"styled_map\", styledMapType);\n map.setMapTypeId(\"styled_map\");\n\n const markers = mapElement.querySelectorAll(\"gmp-advanced-marker\");\n\n markers.forEach((marker) => {\n const dialog = marker.querySelector(\"dialog\");\n const close = dialog.querySelector(\"button\");\n\n marker.addEventListener(\"click\", (domEvent) => {\n this.select(marker);\n map.panTo(marker.position);\n\n //marker.classList.remove(\"hidden\");\n const { target } = domEvent;\n markers.forEach((m) => {\n const otherDialog = m.querySelector(\"dialog\");\n if (otherDialog !== target) {\n otherDialog.close();\n }\n });\n\n if (target === close) {\n if (dialog.open) {\n dialog.close();\n }\n return;\n }\n dialog.show();\n });\n });\n }\n\n /**\n * Adds selected markers\n */\n select(...markers) {\n const event = new CustomEvent(\"gmp-markerschange\", {\n detail: markers,\n });\n this.element.dispatchEvent(event);\n }\n\n /**\n * Renders a cluster as a single marker.\n *\n * Here we clone the first marker in the cluster, assuming that it\n * is an icon, and replace the text content with the count of markers\n * and remove \"icon\" class if any.\n */\n render({ count, position, markers }, stats, map) {\n // Clones the first marker in the cluster.\n const marker = markers[0].cloneNode(true);\n marker.position = position;\n marker.title = `Cluster of ${count} markers`;\n\n const content = marker.querySelector(\"button\");\n content.textContent = count;\n content.classList.remove(\"icon\");\n\n marker.content = content;\n\n marker.addEventListener(\"gmp-click\", () => {\n this.select(...markers);\n });\n\n return marker;\n }\n}\n\nconst maps = document.querySelectorAll(\"gmp-map\");\n\nif (maps.length) {\n (g=>{var h,a,k,p=\"The Google Maps JavaScript API\",c=\"google\",l=\"importLibrary\",q=\"__ib__\",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement(\"script\"));e.set(\"libraries\",[...r]+\"\");for(k in g)e.set(k.replace(/[A-Z]/g,t=>\"_\"+t[0].toLowerCase()),g[k]);e.set(\"callback\",c+\".maps.\"+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+\" could not load.\"));a.nonce=m.querySelector(\"script[nonce]\")?.nonce||\"\";m.head.append(a)}));d[l]?console.warn(p+\" only loads once. Ignoring:\",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({\n key: GOOGLE_MAPS_API_KEY,\n v: \"beta\",\n // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).\n // Add other bootstrap parameters as needed, using camel case.\n });\n\n Promise.all([\n google.maps.importLibrary(\"maps\"),\n google.maps.importLibrary(\"marker\"),\n ]).then(() => {\n maps.forEach((mapElement) => {\n const map = new ClusterMap(mapElement);\n });\n });\n}\n\nconst regionSelector = document.querySelector(\".region-selector\");\nconst mediaQuery = window.matchMedia(\"(max-width: 768px)\");\n\nfunction adjustRegionSelector(){\n if (mediaQuery.matches) {\n regionSelector.removeAttribute(\"open\");\n } else {\n regionSelector.setAttribute(\"open\", \"\");\n }\n}\n\nif (regionSelector) {\n var callResize;\n window.onresize = function(){\n clearTimeout(callResize);\n callResize = setTimeout(adjustRegionSelector, 100);\n };\n adjustRegionSelector();\n}\n", "import {\n cellDataType,\n cellType,\n columnSettingsType,\n inputCellType,\n nodeType,\n textNodeType\n} from \"./types\"\n\n/**\n * Check is item is object\n */\nexport const isObject = (val: (string | number | boolean | object | null | undefined )) => Object.prototype.toString.call(val) === \"[object Object]\"\n\n/**\n * Check for valid JSON string\n */\nexport const isJson = (str: string) => {\n let t = !1\n try {\n t = JSON.parse(str)\n } catch (e) {\n return !1\n }\n return !(null === t || (!Array.isArray(t) && !isObject(t))) && t\n}\n\n/**\n * Create DOM element node\n */\nexport const createElement = (nodeName: string, attrs?: { [key: string]: string}) => {\n const dom = document.createElement(nodeName)\n if (attrs && \"object\" == typeof attrs) {\n for (const attr in attrs) {\n if (\"html\" === attr) {\n dom.innerHTML = attrs[attr]\n } else {\n dom.setAttribute(attr, attrs[attr])\n }\n }\n }\n return dom\n}\n\nexport const objToText = (obj: nodeType) => {\n if ([\"#text\", \"#comment\"].includes(obj.nodeName)) {\n return (obj as textNodeType).data\n }\n if (obj.childNodes) {\n return obj.childNodes.map((childNode: nodeType) => objToText(childNode)).join(\"\")\n }\n return \"\"\n}\n\nexport const cellToText = (obj: inputCellType | cellDataType | null | undefined): string => {\n if (obj === null || obj === undefined) {\n return \"\"\n } else if (obj.hasOwnProperty(\"text\") || obj.hasOwnProperty(\"data\")) {\n const cell = obj as cellType\n return cell.text ?? cellToText(cell.data)\n } else if (obj.hasOwnProperty(\"nodeName\")) {\n return objToText(obj as nodeType)\n }\n return String(obj)\n}\n\n\nexport const escapeText = function(text: string) {\n return text\n .replace(/&/g, \"&\")\n .replace(//g, \">\")\n .replace(/\"/g, \""\")\n}\n\n\nexport const visibleToColumnIndex = function(visibleIndex: number, columns: columnSettingsType[]) {\n let counter = 0\n let columnIndex = 0\n while (counter < (visibleIndex+1)) {\n const columnSettings = columns[columnIndex]\n if (!columnSettings.hidden) {\n counter += 1\n }\n columnIndex += 1\n }\n return columnIndex-1\n}\n\nexport const columnToVisibleIndex = function(columnIndex: number, columns: columnSettingsType[]) {\n let visibleIndex = columnIndex\n let counter = 0\n while (counter < columnIndex) {\n const columnSettings = columns[counter]\n if (columnSettings.hidden) {\n visibleIndex -= 1\n }\n counter++\n }\n return visibleIndex\n}\n\n/**\n * Converts a [NamedNodeMap](https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap) into a normal object.\n *\n * @param map The `NamedNodeMap` to convert\n */\nexport const namedNodeMapToObject = function(map: NamedNodeMap) {\n const obj = {}\n if (map) {\n for (const attr of map) {\n obj[attr.name] = attr.value\n }\n }\n return obj\n}\n\n/**\n * Convert class names to a CSS selector. Multiple classes should be separated by spaces.\n * Examples:\n * - \"my-class\" -> \".my-class\"\n * - \"my-class second-class\" -> \".my-class.second-class\"\n *\n * @param classNames The class names to convert. Can contain multiple classes separated by spaces.\n */\nexport const classNamesToSelector = (classNames: string) => {\n if (!classNames) {\n return null\n }\n return classNames.trim().split(\" \").map(className => `.${className}`).join(\"\")\n}\n\n/**\n * Check if the element contains all the classes. Multiple classes should be separated by spaces.\n *\n * @param element The element that will be checked\n * @param classes The classes that must be present in the element. Can contain multiple classes separated by spaces.\n */\nexport const containsClass = (element: Element, classes: string) => {\n const hasMissingClass = classes?.split(\" \").some(className => !element.classList.contains(className))\n return !hasMissingClass\n}\n\n/**\n * Join two strings with spaces. Null values are ignored.\n * Examples:\n * - joinWithSpaces(\"a\", \"b\") -> \"a b\"\n * - joinWithSpaces(\"a\", null) -> \"a\"\n * - joinWithSpaces(null, \"b\") -> \"b\"\n * - joinWithSpaces(\"a\", \"b c\") -> \"a b c\"\n *\n * @param first The first string to join\n * @param second The second string to join\n */\nexport const joinWithSpaces = (first: string | null | undefined, second: string | null | undefined) => {\n if (first) {\n if (second) {\n return `${first} ${second}`\n }\n return first\n } else if (second) {\n return second\n }\n return \"\"\n}\n\n// Source: https://www.freecodecamp.org/news/javascript-debounce-example/\n\nexport const debounce = function(func: () => void, timeout = 300) {\n let timer: number\n return (..._args: any[]) => {\n clearTimeout(timer)\n timer = window.setTimeout(() => func(), timeout)\n }\n}\n", "/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\n var arguments$1 = arguments;\n\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments$1[i];\r\n for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) { t[p] = s[p]; } }\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) { for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) { ar = Array.prototype.slice.call(from, 0, i); }\r\n ar[i] = from[i];\r\n }\r\n } }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nvar Diff = /** @class */ (function () {\n function Diff(options) {\n if (options === void 0) { options = {}; }\n var _this = this;\n Object.entries(options).forEach(function (_a) {\n var key = _a[0], value = _a[1];\n return (_this[key] = value);\n });\n }\n Diff.prototype.toString = function () {\n return JSON.stringify(this);\n };\n Diff.prototype.setValue = function (aKey, aValue) {\n this[aKey] = aValue;\n return this;\n };\n return Diff;\n}());\nfunction checkElementType(element) {\n var arguments$1 = arguments;\n\n var elementTypeNames = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n elementTypeNames[_i - 1] = arguments$1[_i];\n }\n if (typeof element === \"undefined\" || element === null) {\n return false;\n }\n return elementTypeNames.some(function (elementTypeName) {\n var _a, _b;\n // We need to check if the specified type is defined\n // because otherwise instanceof throws an exception.\n return typeof ((_b = (_a = element === null || element === void 0 ? void 0 : element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b[elementTypeName]) ===\n \"function\" &&\n element instanceof\n element.ownerDocument.defaultView[elementTypeName];\n });\n}\n\nfunction objToNode(objNode, insideSvg, options) {\n var node;\n if (objNode.nodeName === \"#text\") {\n node = options.document.createTextNode(objNode.data);\n }\n else if (objNode.nodeName === \"#comment\") {\n node = options.document.createComment(objNode.data);\n }\n else {\n if (insideSvg) {\n node = options.document.createElementNS(\"http://www.w3.org/2000/svg\", objNode.nodeName);\n if (objNode.nodeName === \"foreignObject\") {\n insideSvg = false;\n }\n }\n else if (objNode.nodeName.toLowerCase() === \"svg\") {\n node = options.document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n insideSvg = true;\n }\n else {\n node = options.document.createElement(objNode.nodeName);\n }\n if (objNode.attributes) {\n Object.entries(objNode.attributes).forEach(function (_a) {\n var key = _a[0], value = _a[1];\n return node.setAttribute(key, value);\n });\n }\n if (objNode.childNodes) {\n node = node;\n objNode.childNodes.forEach(function (childNode) {\n return node.appendChild(objToNode(childNode, insideSvg, options));\n });\n }\n if (options.valueDiffing) {\n if (objNode.value &&\n checkElementType(node, \"HTMLButtonElement\", \"HTMLDataElement\", \"HTMLInputElement\", \"HTMLLIElement\", \"HTMLMeterElement\", \"HTMLOptionElement\", \"HTMLProgressElement\", \"HTMLParamElement\")) {\n node.value = objNode.value;\n }\n if (objNode.checked && checkElementType(node, \"HTMLInputElement\")) {\n node.checked = objNode.checked;\n }\n if (objNode.selected &&\n checkElementType(node, \"HTMLOptionElement\")) {\n node.selected = objNode.selected;\n }\n }\n }\n return node;\n}\n\n// ===== Apply a diff =====\nvar getFromRoute = function (node, route) {\n route = route.slice();\n while (route.length > 0) {\n var c = route.splice(0, 1)[0];\n node = node.childNodes[c];\n }\n return node;\n};\nfunction applyDiff(tree, diff, options) {\n var action = diff[options._const.action];\n var route = diff[options._const.route];\n var node;\n if (![options._const.addElement, options._const.addTextElement].includes(action)) {\n // For adding nodes, we calculate the route later on. It's different because it includes the position of the newly added item.\n node = getFromRoute(tree, route);\n }\n var newNode;\n var reference;\n var nodeArray;\n // pre-diff hook\n var info = {\n diff: diff,\n node: node\n };\n if (options.preDiffApply(info)) {\n return true;\n }\n switch (action) {\n case options._const.addAttribute:\n if (!node || !checkElementType(node, \"Element\")) {\n return false;\n }\n node.setAttribute(diff[options._const.name], diff[options._const.value]);\n break;\n case options._const.modifyAttribute:\n if (!node || !checkElementType(node, \"Element\")) {\n return false;\n }\n node.setAttribute(diff[options._const.name], diff[options._const.newValue]);\n if (checkElementType(node, \"HTMLInputElement\") &&\n diff[options._const.name] === \"value\") {\n node.value = diff[options._const.newValue];\n }\n break;\n case options._const.removeAttribute:\n if (!node || !checkElementType(node, \"Element\")) {\n return false;\n }\n node.removeAttribute(diff[options._const.name]);\n break;\n case options._const.modifyTextElement:\n if (!node || !checkElementType(node, \"Text\")) {\n return false;\n }\n options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue]);\n if (checkElementType(node.parentNode, \"HTMLTextAreaElement\")) {\n node.parentNode.value = diff[options._const.newValue];\n }\n break;\n case options._const.modifyValue:\n if (!node || typeof node.value === \"undefined\") {\n return false;\n }\n node.value = diff[options._const.newValue];\n break;\n case options._const.modifyComment:\n if (!node || !checkElementType(node, \"Comment\")) {\n return false;\n }\n options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue]);\n break;\n case options._const.modifyChecked:\n if (!node || typeof node.checked === \"undefined\") {\n return false;\n }\n node.checked = diff[options._const.newValue];\n break;\n case options._const.modifySelected:\n if (!node || typeof node.selected === \"undefined\") {\n return false;\n }\n node.selected = diff[options._const.newValue];\n break;\n case options._const.replaceElement: {\n var insideSvg = diff[options._const.newValue].nodeName.toLowerCase() === \"svg\" ||\n node.parentNode.namespaceURI === \"http://www.w3.org/2000/svg\";\n node.parentNode.replaceChild(objToNode(diff[options._const.newValue], insideSvg, options), node);\n break;\n }\n case options._const.relocateGroup:\n nodeArray = __spreadArray([], new Array(diff[options._const.groupLength]), true).map(function () {\n return node.removeChild(node.childNodes[diff[options._const.from]]);\n });\n nodeArray.forEach(function (childNode, index) {\n if (index === 0) {\n reference =\n node.childNodes[diff[options._const.to]];\n }\n node.insertBefore(childNode, reference || null);\n });\n break;\n case options._const.removeElement:\n node.parentNode.removeChild(node);\n break;\n case options._const.addElement: {\n var parentRoute = route.slice();\n var c = parentRoute.splice(parentRoute.length - 1, 1)[0];\n node = getFromRoute(tree, parentRoute);\n if (!checkElementType(node, \"Element\")) {\n return false;\n }\n node.insertBefore(objToNode(diff[options._const.element], node.namespaceURI === \"http://www.w3.org/2000/svg\", options), node.childNodes[c] || null);\n break;\n }\n case options._const.removeTextElement: {\n if (!node || node.nodeType !== 3) {\n return false;\n }\n var parentNode = node.parentNode;\n parentNode.removeChild(node);\n if (checkElementType(parentNode, \"HTMLTextAreaElement\")) {\n parentNode.value = \"\";\n }\n break;\n }\n case options._const.addTextElement: {\n var parentRoute = route.slice();\n var c = parentRoute.splice(parentRoute.length - 1, 1)[0];\n newNode = options.document.createTextNode(diff[options._const.value]);\n node = getFromRoute(tree, parentRoute);\n if (!node.childNodes) {\n return false;\n }\n node.insertBefore(newNode, node.childNodes[c] || null);\n if (checkElementType(node.parentNode, \"HTMLTextAreaElement\")) {\n node.parentNode.value = diff[options._const.value];\n }\n break;\n }\n default:\n console.log(\"unknown action\");\n }\n // if a new node was created, we might be interested in its\n // post diff hook\n options.postDiffApply({\n diff: info.diff,\n node: info.node,\n newNode: newNode\n });\n return true;\n}\nfunction applyDOM(tree, diffs, options) {\n return diffs.every(function (diff) {\n return applyDiff(tree, diff, options);\n });\n}\n\n// ===== Undo a diff =====\nfunction swap(obj, p1, p2) {\n var tmp = obj[p1];\n obj[p1] = obj[p2];\n obj[p2] = tmp;\n}\nfunction undoDiff(tree, diff, options) {\n switch (diff[options._const.action]) {\n case options._const.addAttribute:\n diff[options._const.action] = options._const.removeAttribute;\n applyDiff(tree, diff, options);\n break;\n case options._const.modifyAttribute:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.removeAttribute:\n diff[options._const.action] = options._const.addAttribute;\n applyDiff(tree, diff, options);\n break;\n case options._const.modifyTextElement:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.modifyValue:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.modifyComment:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.modifyChecked:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.modifySelected:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.replaceElement:\n swap(diff, options._const.oldValue, options._const.newValue);\n applyDiff(tree, diff, options);\n break;\n case options._const.relocateGroup:\n swap(diff, options._const.from, options._const.to);\n applyDiff(tree, diff, options);\n break;\n case options._const.removeElement:\n diff[options._const.action] = options._const.addElement;\n applyDiff(tree, diff, options);\n break;\n case options._const.addElement:\n diff[options._const.action] = options._const.removeElement;\n applyDiff(tree, diff, options);\n break;\n case options._const.removeTextElement:\n diff[options._const.action] = options._const.addTextElement;\n applyDiff(tree, diff, options);\n break;\n case options._const.addTextElement:\n diff[options._const.action] = options._const.removeTextElement;\n applyDiff(tree, diff, options);\n break;\n default:\n console.log(\"unknown action\");\n }\n}\nfunction undoDOM(tree, diffs, options) {\n diffs = diffs.slice();\n diffs.reverse();\n diffs.forEach(function (diff) {\n undoDiff(tree, diff, options);\n });\n}\n\nvar elementDescriptors = function (el) {\n var output = [];\n output.push(el.nodeName);\n if (el.nodeName !== \"#text\" && el.nodeName !== \"#comment\") {\n el = el;\n if (el.attributes) {\n if (el.attributes[\"class\"]) {\n output.push(\"\".concat(el.nodeName, \".\").concat(el.attributes[\"class\"].replace(/ /g, \".\")));\n }\n if (el.attributes.id) {\n output.push(\"\".concat(el.nodeName, \"#\").concat(el.attributes.id));\n }\n }\n }\n return output;\n};\nvar findUniqueDescriptors = function (li) {\n var uniqueDescriptors = {};\n var duplicateDescriptors = {};\n li.forEach(function (node) {\n elementDescriptors(node).forEach(function (descriptor) {\n var inUnique = descriptor in uniqueDescriptors;\n var inDupes = descriptor in duplicateDescriptors;\n if (!inUnique && !inDupes) {\n uniqueDescriptors[descriptor] = true;\n }\n else if (inUnique) {\n delete uniqueDescriptors[descriptor];\n duplicateDescriptors[descriptor] = true;\n }\n });\n });\n return uniqueDescriptors;\n};\nvar uniqueInBoth = function (l1, l2) {\n var l1Unique = findUniqueDescriptors(l1);\n var l2Unique = findUniqueDescriptors(l2);\n var inBoth = {};\n Object.keys(l1Unique).forEach(function (key) {\n if (l2Unique[key]) {\n inBoth[key] = true;\n }\n });\n return inBoth;\n};\nvar removeDone = function (tree) {\n delete tree.outerDone;\n delete tree.innerDone;\n delete tree.valueDone;\n if (tree.childNodes) {\n return tree.childNodes.every(removeDone);\n }\n else {\n return true;\n }\n};\nvar cleanNode = function (diffNode) {\n if (Object.prototype.hasOwnProperty.call(diffNode, \"data\")) {\n var textNode = {\n nodeName: diffNode.nodeName === \"#text\" ? \"#text\" : \"#comment\",\n data: diffNode.data\n };\n return textNode;\n }\n else {\n var elementNode = {\n nodeName: diffNode.nodeName\n };\n diffNode = diffNode;\n if (Object.prototype.hasOwnProperty.call(diffNode, \"attributes\")) {\n elementNode.attributes = __assign({}, diffNode.attributes);\n }\n if (Object.prototype.hasOwnProperty.call(diffNode, \"checked\")) {\n elementNode.checked = diffNode.checked;\n }\n if (Object.prototype.hasOwnProperty.call(diffNode, \"value\")) {\n elementNode.value = diffNode.value;\n }\n if (Object.prototype.hasOwnProperty.call(diffNode, \"selected\")) {\n elementNode.selected = diffNode.selected;\n }\n if (Object.prototype.hasOwnProperty.call(diffNode, \"childNodes\")) {\n elementNode.childNodes = diffNode.childNodes.map(function (diffChildNode) {\n return cleanNode(diffChildNode);\n });\n }\n return elementNode;\n }\n};\nvar isEqual = function (e1, e2) {\n if (![\"nodeName\", \"value\", \"checked\", \"selected\", \"data\"].every(function (element) {\n if (e1[element] !== e2[element]) {\n return false;\n }\n return true;\n })) {\n return false;\n }\n if (Object.prototype.hasOwnProperty.call(e1, \"data\")) {\n // Comment or Text\n return true;\n }\n e1 = e1;\n e2 = e2;\n if (Boolean(e1.attributes) !== Boolean(e2.attributes)) {\n return false;\n }\n if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) {\n return false;\n }\n if (e1.attributes) {\n var e1Attributes = Object.keys(e1.attributes);\n var e2Attributes = Object.keys(e2.attributes);\n if (e1Attributes.length !== e2Attributes.length) {\n return false;\n }\n if (!e1Attributes.every(function (attribute) {\n if (e1.attributes[attribute] !==\n e2.attributes[attribute]) {\n return false;\n }\n return true;\n })) {\n return false;\n }\n }\n if (e1.childNodes) {\n if (e1.childNodes.length !== e2.childNodes.length) {\n return false;\n }\n if (!e1.childNodes.every(function (childNode, index) {\n return isEqual(childNode, e2.childNodes[index]);\n })) {\n return false;\n }\n }\n return true;\n};\nvar roughlyEqual = function (e1, e2, uniqueDescriptors, sameSiblings, preventRecursion) {\n if (preventRecursion === void 0) { preventRecursion = false; }\n if (!e1 || !e2) {\n return false;\n }\n if (e1.nodeName !== e2.nodeName) {\n return false;\n }\n if ([\"#text\", \"#comment\"].includes(e1.nodeName)) {\n // Note that we initially don't care what the text content of a node is,\n // the mere fact that it's the same tag and \"has text\" means it's roughly\n // equal, and then we can find out the true text difference later.\n return preventRecursion\n ? true\n : e1.data === e2.data;\n }\n e1 = e1;\n e2 = e2;\n if (e1.nodeName in uniqueDescriptors) {\n return true;\n }\n if (e1.attributes && e2.attributes) {\n if (e1.attributes.id) {\n if (e1.attributes.id !== e2.attributes.id) {\n return false;\n }\n else {\n var idDescriptor = \"\".concat(e1.nodeName, \"#\").concat(e1.attributes.id);\n if (idDescriptor in uniqueDescriptors) {\n return true;\n }\n }\n }\n if (e1.attributes[\"class\"] &&\n e1.attributes[\"class\"] === e2.attributes[\"class\"]) {\n var classDescriptor = \"\".concat(e1.nodeName, \".\").concat(e1.attributes[\"class\"].replace(/ /g, \".\"));\n if (classDescriptor in uniqueDescriptors) {\n return true;\n }\n }\n }\n if (sameSiblings) {\n return true;\n }\n var nodeList1 = e1.childNodes ? e1.childNodes.slice().reverse() : [];\n var nodeList2 = e2.childNodes ? e2.childNodes.slice().reverse() : [];\n if (nodeList1.length !== nodeList2.length) {\n return false;\n }\n if (preventRecursion) {\n return nodeList1.every(function (element, index) {\n return element.nodeName === nodeList2[index].nodeName;\n });\n }\n else {\n // note: we only allow one level of recursion at any depth. If 'preventRecursion'\n // was not set, we must explicitly force it to true for child iterations.\n var childUniqueDescriptors_1 = uniqueInBoth(nodeList1, nodeList2);\n return nodeList1.every(function (element, index) {\n return roughlyEqual(element, nodeList2[index], childUniqueDescriptors_1, true, true);\n });\n }\n};\n/**\n * based on https://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#JavaScript\n */\nvar findCommonSubsets = function (c1, c2, marked1, marked2) {\n var lcsSize = 0;\n var index = [];\n var c1Length = c1.length;\n var c2Length = c2.length;\n var // set up the matching table\n matches = __spreadArray([], new Array(c1Length + 1), true).map(function () { return []; });\n var uniqueDescriptors = uniqueInBoth(c1, c2);\n var // If all of the elements are the same tag, id and class, then we can\n // consider them roughly the same even if they have a different number of\n // children. This will reduce removing and re-adding similar elements.\n subsetsSame = c1Length === c2Length;\n if (subsetsSame) {\n c1.some(function (element, i) {\n var c1Desc = elementDescriptors(element);\n var c2Desc = elementDescriptors(c2[i]);\n if (c1Desc.length !== c2Desc.length) {\n subsetsSame = false;\n return true;\n }\n c1Desc.some(function (description, i) {\n if (description !== c2Desc[i]) {\n subsetsSame = false;\n return true;\n }\n });\n if (!subsetsSame) {\n return true;\n }\n });\n }\n // fill the matches with distance values\n for (var c1Index = 0; c1Index < c1Length; c1Index++) {\n var c1Element = c1[c1Index];\n for (var c2Index = 0; c2Index < c2Length; c2Index++) {\n var c2Element = c2[c2Index];\n if (!marked1[c1Index] &&\n !marked2[c2Index] &&\n roughlyEqual(c1Element, c2Element, uniqueDescriptors, subsetsSame)) {\n matches[c1Index + 1][c2Index + 1] = matches[c1Index][c2Index]\n ? matches[c1Index][c2Index] + 1\n : 1;\n if (matches[c1Index + 1][c2Index + 1] >= lcsSize) {\n lcsSize = matches[c1Index + 1][c2Index + 1];\n index = [c1Index + 1, c2Index + 1];\n }\n }\n else {\n matches[c1Index + 1][c2Index + 1] = 0;\n }\n }\n }\n if (lcsSize === 0) {\n return false;\n }\n return {\n oldValue: index[0] - lcsSize,\n newValue: index[1] - lcsSize,\n length: lcsSize\n };\n};\nvar makeBooleanArray = function (n, v) {\n return __spreadArray([], new Array(n), true).map(function () { return v; });\n};\n/**\n * Generate arrays that indicate which node belongs to which subset,\n * or whether it's actually an orphan node, existing in only one\n * of the two trees, rather than somewhere in both.\n *\n * So if t1 = ![]()