{"version":3,"sources":["webpack:///./app/webpacker/src/javascripts/_availability_table.js","webpack:///./app/webpacker/src/javascripts/_highlight.ts","webpack:///./app/webpacker/packs/show.js"],"names":["updateStatusElement","itemEl","itemStatus","arguments","length","undefined","holdCount","availabilityEl","querySelector","dataset","statusCode","code","replaceChildren","appendChild","statusDueDate","duedate","statusData","getStatusData","newEl","document","createElement","statusEl","holdEl","onHold","classList","add","textContent","bsTitle","bsToggle","append","dueDate","moment","format","innerHTML","prepend","label","display","desc","createStatusElement","availRows","parentNode","querySelectorAll","requestColumn","forEach","el","itemRequestability","shouldShowRequestColumn","remove","revealRequestColumn","innerText","updateLocationElement","itemLocation","locationEl","locationCode","getLocationData","statusText","statusSpan","title","linkEl","href","updateAeonRequestUrl","aeonUrl","locationData","locationText","name","linkText","url","target","modalText","elIcon","modalId","Math","floor","random","setAttribute","style","marginRight","modal","id","body","createLocationLink","checkEmptyTable","availTable","primaryItems","moreItems","cardBody","addNoItemsMessage","repositionItemElements","primaryCount","i","firstItem","removeChild","updateItemIndices","index","itemIndex","updateCatalogRequestURLs","row","rowIndex","requestLink","requestUrl","catalogUrl","URL","queryString","search","replace","toString","updateNoApiItems","getPlaceholderItemsElements","item","availEl","itemLoc","serviceDesk","getServiceDeskData","async","checkAvailability","chunkedItemBibs","getItemsIDs","allItemBibs","flat","promises","map","callSierraApi","chunk","error","items","availabilityTable","updateUIError","filter","includes","Promise","allSettled","then","result","foundItems","itemsFromPromises","missingItems","status","location","updateUI","findMissing","finally","moreItemsTable","moreLessButton","childElementCount","contains","checkMoreLink","highlightSearchTerms","parseUserQuery","userQuery","allStopwords","asPhrasesOnly","qterms","q","split","reduce","env","term","insideQuotes","trimmed","trim","parsed","wordEnv","word","j","original","normWord","lastWord","terms","atAlphaNumTransition","test","join","atEndOfLoop","wordStack","push","phrasesOnly","every","indexOf","queryToTerms","toLowerCase","concat","phrases","doStack","mainTerm","stack","forward","swTerm","swStack","termArray","slice","stopwordStack","previousMainTerm","finalPhrases","termsToPhrases","justTerms","Set","myStopwords","searchData","searchContextEl","getElementById","searchContext","JSON","parse","getSearchData","searchType","search_field","searchFields","instance","termList","Mark","field","unmark","done","termRe","diacritics","wordDelimitersRe","finalTermList","RegExp","char","charRe","dct","x","termsToRegExp","markRegExp","className","exclude","ignoreGroups","regExpMark","addEventListener","setDocHistory","bindShowAvailMoreField","replaceBookCovers","hoverHierarchicalLinks"],"mappings":"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","file":"js/show-acbb5bfec821592ecc1e.chunk.js","sourcesContent":["import moment from 'moment';\nimport {\n callSierraApi,\n findMissing,\n getItemsIDs,\n getLocationData,\n getPlaceholderItemsElements,\n getServiceDeskData,\n getStatusData,\n itemsFromPromises,\n updateAeonRequestUrl,\n} from './_availability_util';\n\n/**\n * FUNCTIONS FOR `SHOW` VIEWS\n */\n\n/**\n * Accesses the mapped location data to determine the URL to use for linkage\n * @param {Object} itemLocation\n * @return {(HTMLElement)}\n */\nfunction createLocationLink(itemLocation) {\n const locationData = getLocationData(itemLocation.code);\n const locationText = locationData.name ? locationData.name : itemLocation.name;\n const linkText = locationData.linkText ? locationData.linkText : itemLocation.name;\n if (locationData && locationData.url) {\n const newEl = document.createElement('a');\n newEl.textContent = locationText;\n newEl.href = locationData.url;\n newEl.title = linkText;\n newEl.target = '_blank';\n return newEl;\n }\n\n if (locationData && locationData.modalText) {\n const newEl = document.createElement('a');\n const elIcon = document.createElement('i');\n const modalId = `modal${Math.floor(Math.random() * 1000)}`;\n newEl.textContent = locationText;\n newEl.href = '#';\n newEl.setAttribute('data-bs-toggle', 'modal');\n newEl.setAttribute('data-bs-target', `#${modalId}`);\n elIcon.classList.add('icon', 'fal', `fa-info-circle`);\n elIcon.style.marginRight = '0.25em';\n newEl.prepend(elIcon);\n\n const modal = document.createElement('div');\n modal.classList.add('modal', 'fade');\n modal.id = modalId;\n modal.setAttribute('tabindex', '-1');\n modal.setAttribute('role', 'dialog');\n modal.setAttribute('aria-labelledby', `${modalId}Label`);\n modal.setAttribute('aria-hidden', 'true');\n modal.innerHTML = `\n
\n
\n
\n

${linkText}

\n \n
\n
${locationData.modalText}
\n
\n
\n `;\n document.body.appendChild(modal);\n\n return newEl;\n }\n const newEl = document.createElement('span');\n newEl.textContent = locationText;\n return newEl;\n}\n\n/**\n * Accesses the mapped item status to add a tooltip and create an element\n * @param {Object} itemStatus\n * @param {int} holdCount\n * @return {(HTMLElement)}\n */\nfunction createStatusElement(itemStatus, holdCount) {\n const statusCode = itemStatus.code;\n const statusDueDate = itemStatus.duedate;\n const statusData = getStatusData(statusCode);\n const newEl = document.createElement('span');\n const statusEl = document.createElement('div');\n const holdEl = document.createElement('div');\n const onHold = holdCount > 0;\n\n statusEl.classList.add('status-text');\n\n if (onHold) {\n holdEl.classList.add('hold-text', 'tooltip-nolink');\n holdEl.textContent = `On Hold (${holdCount} ${holdCount > 1 ? 'Holds' : 'Hold'})`;\n holdEl.dataset.bsTitle = `${holdCount} other patron${holdCount > 1 ? 's have' : ' has'} requested this item and ${holdCount > 1 ? 'are' : ' is'} queued to check it out before it becomes available.`;\n holdEl.dataset.bsToggle = 'tooltip';\n newEl.append(holdEl);\n\n // If the item status is available and not checked out, return the hold message\n if (statusCode === '-' && !statusDueDate) {\n return newEl;\n }\n }\n\n // If the item is checked out\n if (statusDueDate) {\n const dueDate = moment(itemStatus.duedate).format('MMM DD, YYYY');\n statusEl.innerHTML = `Checked out
Due ${dueDate}`;\n newEl.prepend(statusEl);\n return newEl;\n }\n\n // Use the status label if present, otherwise the item display\n if (statusData && statusData.label) {\n statusEl.textContent = statusData.label;\n newEl.prepend(statusEl);\n } else {\n statusEl.textContent = itemStatus.display;\n newEl.prepend(statusEl);\n }\n\n // Add a tooltip for the status description if present\n if (statusData && statusData.desc) {\n statusEl.classList.add('tooltip-nolink');\n statusEl.dataset.bsTitle = statusData.desc;\n statusEl.dataset.bsToggle = 'tooltip';\n }\n\n return newEl;\n}\n\n/**\n * Determine whether to show the request column if one of the items is not an online item\n * @param {(HTMLElement|Element)} itemEl\n * @param {Object} itemStatus\n * @return {Boolean} Whether to show the request column\n */\nfunction shouldShowRequestColumn(itemEl, itemStatus) {\n if (itemStatus.code === 'w') return false;\n const availTableBody = itemEl.parentNode;\n const availRows = availTableBody.querySelectorAll('.item-row');\n let requestColumn = false;\n\n availRows.forEach((el) => {\n if (el.dataset.itemRequestability) {\n requestColumn = true;\n }\n });\n return requestColumn;\n}\n\n/**\n * Reveal the request column for all items\n * @param {(HTMLElement|Element)} itemEl\n */\nfunction revealRequestColumn(itemEl) {\n const availTableBody = itemEl.parentNode;\n const availTable = availTableBody.parentNode;\n const requestEls = availTable.querySelectorAll('.blacklight-request.d-none');\n\n requestEls.forEach((el) => {\n el.classList.remove('d-none');\n });\n}\n\n/**\n * Updates the status element for an item, including due date\n * @param {(HTMLElement|Element|Node)} itemEl\n * @param {Object} itemStatus\n * @param {int} holdCount\n */\nfunction updateStatusElement(itemEl, itemStatus = null, holdCount = 0) {\n const availabilityEl = itemEl.querySelector('.blacklight-availability.result__value');\n\n if (!itemStatus) {\n availabilityEl.innerText = 'Ask at the Service Desk';\n return;\n }\n\n availabilityEl.dataset.statusCode = itemStatus.code;\n availabilityEl.replaceChildren();\n availabilityEl.appendChild(createStatusElement(itemStatus, holdCount));\n\n // Show the Request column if this isn't an online only record\n if (shouldShowRequestColumn(itemEl, itemStatus)) {\n revealRequestColumn(itemEl);\n }\n}\n\n/**\n * Updates the location element for an item and calls function to update Aeon URL if necessary\n * @param {(HTMLElement|Element|Node)} itemEl\n * @param {Object} itemLocation\n */\nfunction updateLocationElement(itemEl, itemLocation) {\n if (!itemLocation) return;\n\n const locationEl = itemEl.querySelector('.blacklight-location.result__value');\n\n locationEl.dataset.locationCode = itemLocation.code;\n\n // Check for location tooltip that would override status tooltip\n if (getLocationData(itemLocation.code).statusText) {\n const statusSpan = itemEl.querySelector('.blacklight-availability .status-text');\n if (statusSpan) {\n statusSpan.dataset.title = getLocationData(itemLocation.code).statusText;\n }\n }\n\n // Aeon request URLs must be updated to include data from the Sierra API call\n if (itemEl.dataset.itemRequestability === 'aeon') {\n const linkEl = itemEl.querySelector('.request-aeon');\n linkEl.href = updateAeonRequestUrl(linkEl.href, itemLocation);\n } else if (itemEl.dataset.itemRequestability === 'catalog') {\n const linkEl = itemEl.querySelector('.request-catalog');\n linkEl.dataset.aeonUrl = updateAeonRequestUrl(linkEl.dataset.aeonUrl, itemLocation);\n }\n\n locationEl.appendChild(createLocationLink(itemLocation));\n}\n\nfunction addNoItemsMessage() {\n const itemAvailabilityCard = document.querySelector('.item-availability');\n const cardBody = itemAvailabilityCard.querySelector('.card-body');\n const newEl = document.createElement('div');\n\n newEl.innerHTML = 'No items found. Please contact the Willis Library Service Desk for assistance';\n cardBody.appendChild(newEl);\n}\n\nfunction checkMoreLink() {\n const availTable = document.querySelector('#availabilityTable');\n const moreItemsTable = availTable.querySelector('tbody#moreItems');\n if (moreItemsTable === null) return;\n const moreLessButton = availTable.querySelector('tbody#moreLessButton');\n\n if (moreItemsTable.childElementCount === 0 && !moreLessButton.classList.contains('d-none')) {\n moreLessButton.classList.add('d-none');\n } else {\n moreLessButton.classList.remove('d-none');\n }\n}\n\nfunction checkEmptyTable() {\n const availTable = document.querySelector('#availabilityTable');\n if (availTable === null) return;\n const primaryItems = availTable.querySelectorAll('tbody#primaryItems .item-row');\n const moreItems = availTable.querySelectorAll('tbody#moreItems .item-row');\n\n if (primaryItems.length === 0 && moreItems.length === 0) {\n availTable.remove();\n addNoItemsMessage();\n }\n}\n\n/**\n * Checks if the list of links includes a fulltext link, indicating that this is an online only item\n * @returns {boolean}\n */\nfunction isOnlineOnly() {\n const links = document.querySelectorAll('[data-link-type=\\'fulltext\\'].link-media-item');\n return links.length > 0;\n}\n\nfunction repositionItemElements() {\n const availTable = document.querySelector('#availabilityTable');\n const primaryItems = availTable.querySelector('#primaryItems');\n const moreItems = availTable.querySelector('#moreItems');\n if (moreItems === null) return;\n\n const primaryMax = 3;\n const primaryCount = primaryItems.querySelectorAll('.item-row').length;\n\n if (primaryCount < primaryMax) {\n for (let i = 0; i < 3 - primaryCount; i += 1) {\n const firstItem = moreItems.querySelector('.item-row');\n if (firstItem !== null) {\n firstItem.parentNode.removeChild(firstItem);\n primaryItems.appendChild(firstItem);\n }\n }\n }\n}\n\nfunction updateItemIndices() {\n const availTable = document.querySelector('#availabilityTable');\n if (availTable === null) return;\n const itemRows = availTable.querySelectorAll('.item-row');\n\n itemRows.forEach((itemEl, index) => {\n // eslint-disable-next-line no-param-reassign\n itemEl.dataset.itemIndex = index;\n });\n}\n\nfunction updateCatalogRequestURLs() {\n const availTable = document.querySelector('#availabilityTable');\n if (availTable === null) return;\n const itemRows = availTable.querySelectorAll('.item-row');\n\n itemRows.forEach((row) => {\n if (row.dataset.itemRequestability !== 'catalog') return;\n\n const rowIndex = row.dataset.itemIndex;\n const requestCell = row.querySelector('.blacklight-request.result__value');\n const requestLink = requestCell.querySelector('a');\n const requestUrl = requestLink.href;\n const catalogUrl = new URL(requestUrl);\n const queryString = catalogUrl.search;\n\n catalogUrl.search = queryString.replace(/(requestItemIndex=)(\\d*)/i, `$1${rowIndex}`);\n requestLink.href = catalogUrl.toString();\n });\n}\n\nfunction updateUIError(items, error = undefined) {\n const availabilityTable = document.querySelector('#availabilityTable');\n if (availabilityTable === null) return;\n\n items.forEach((item) => {\n const itemEl = availabilityTable.querySelector(`[data-item-id='${item}']`);\n if (itemEl === null) return;\n if (error === 107) {\n itemEl.remove();\n } else {\n const availabilityEl = itemEl.querySelector('.blacklight-availability.result__value');\n availabilityEl.innerText = 'Ask at the Service Desk';\n }\n });\n if (error === 107) {\n updateItemIndices();\n repositionItemElements();\n updateCatalogRequestURLs();\n }\n}\n\n/**\n * Calls UI update functions for items returned by the Sierra API as well as those missing\n * @param {Array} foundItems\n * @param {Array} missingItems\n */\nfunction updateUI(foundItems = [], missingItems = []) {\n const availabilityTable = document.querySelector('#availabilityTable');\n if (availabilityTable === null) return;\n\n foundItems.forEach((item) => {\n const itemEl = availabilityTable.querySelector(`[data-item-id='${item.id}']`);\n if (itemEl === null) return;\n updateStatusElement(itemEl, item.status, item.holdCount);\n updateLocationElement(itemEl, item.location);\n });\n\n missingItems.forEach((item) => {\n const itemEl = availabilityTable.querySelector(`[data-item-id='${item}']`);\n if (itemEl === null) return;\n itemEl.remove();\n // console.log(`Item ${item} not returned by the API`);\n });\n\n if (missingItems.length > 0) {\n updateItemIndices();\n repositionItemElements();\n updateCatalogRequestURLs();\n }\n}\n\n/**\n * Update UI elements for items that are \"fake\" and should not be included in the API call\n */\nfunction updateNoApiItems() {\n const noApiElements = getPlaceholderItemsElements();\n\n noApiElements.forEach((item) => {\n const locationEl = item.querySelector('.blacklight-location.result__value');\n if (locationEl === null) return;\n const availEl = item.querySelector('.blacklight-availability.result__value');\n\n if (isOnlineOnly()) {\n // Set specific status and location codes to get the data we want.\n const itemStatus = { code: 'w' };\n const itemLoc = { code: 'lwww' };\n updateStatusElement(item, itemStatus);\n updateLocationElement(item, itemLoc);\n } else {\n const locationCode = locationEl.dataset.itemLocation;\n const locationData = getLocationData(locationCode);\n const serviceDesk = getServiceDeskData(locationCode);\n locationData.code = locationCode;\n updateLocationElement(item, locationData);\n availEl.innerHTML = `Unknown: Contact the Service Desk`;\n }\n });\n}\n\n/**\n * Main function for checking availability on Show view.\n * @returns {Promise}\n */\nasync function checkAvailability() {\n const chunkedItemBibs = getItemsIDs();\n let allItemBibs = chunkedItemBibs.flat();\n\n updateNoApiItems();\n\n // Create a map of chunked bib numbers that will return promises\n const promises = chunkedItemBibs.map(async (chunk) => {\n try {\n return await callSierraApi(chunk);\n } catch (error) {\n // Update items that returned a Sierra API error and remove them from further UI updates\n // console.log(`Sierra API error ${error.code}: ${error.name}`);\n updateUIError(chunk, error.code);\n allItemBibs = allItemBibs.filter((el) => !chunk.includes(el));\n return error;\n }\n });\n\n await Promise.allSettled(promises)\n .then((result) => {\n let foundItems = itemsFromPromises(result);\n\n // Error from the Sierra API\n if (foundItems[0] === undefined) {\n foundItems = [];\n }\n\n const missingItems = findMissing(foundItems, allItemBibs);\n updateUI(foundItems, missingItems);\n }).finally(() => {\n checkMoreLink();\n checkEmptyTable();\n });\n}\n\nexport {\n // eslint-disable-next-line import/prefer-default-export\n checkAvailability,\n};\n","import Mark from 'mark.js';\n\n/**\n * Uses mark.js to highlight search terms in Show view\n */\nfunction highlightSearchTerms(): void {\n /**\n * Converts a user query string to two arrays:\n * @param {string} q\n * @param {Array} allStopwords\n * @param {boolean} asPhrasesOnly Whether to treat this as a call number or not\n * @return {Object}\n * terms {Array} list of individual terms from the user query, in query order\n * phrasesOnly {Array} list of hyphenated phrases for e.g. call numbers or parts of call numbers\n */\n // eslint-disable-next-line max-len\n function queryToTerms(q: string, allStopwords: string[], asPhrasesOnly: boolean): { terms: string[], phrasesOnly: string[] } {\n return q.split('\"').reduce((env, term, i) => {\n const insideQuotes = i % 2;\n const trimmed = term.trim();\n const parsed = trimmed.split(/\\p{P}*\\s+\\p{P}*/u).reduce((wordEnv, word, j, original) => {\n if (word !== '') {\n const normWord = word.replace(/(?:(\\p{L})(\\p{N})|(\\p{N})(\\p{L}))/u, '$1$3-$2$4');\n const lastWord = wordEnv.terms.length > 0 ? wordEnv.terms[wordEnv.terms.length - 1] : '';\n const atAlphaNumTransition = lastWord !== '' && /(\\p{L}~!!~\\p{N}|\\p{N}~!!~\\p{L})/u.test([lastWord, normWord].join('~!!~'));\n const atEndOfLoop = j === original.length - 1;\n if (asPhrasesOnly || atAlphaNumTransition) {\n wordEnv.wordStack.push(normWord);\n }\n if (atEndOfLoop || (!asPhrasesOnly && !atAlphaNumTransition)) {\n if (asPhrasesOnly || wordEnv.wordStack.length > 1) {\n wordEnv.phrasesOnly.push(wordEnv.wordStack.join('-'));\n }\n // eslint-disable-next-line no-param-reassign\n wordEnv.wordStack = [normWord];\n }\n wordEnv.terms.push(normWord);\n }\n return wordEnv;\n }, {\n terms: [] as string[],\n phrasesOnly: [] as string[],\n wordStack: [] as string[],\n });\n if (insideQuotes && parsed.terms.every((word) => allStopwords.indexOf(word) > -1)) {\n env.terms.push(trimmed);\n } else {\n env.terms.push(...parsed.terms);\n }\n env.phrasesOnly.push(...parsed.phrasesOnly);\n return env;\n }, {\n terms: [] as string[],\n phrasesOnly: [] as string[],\n });\n }\n\n /**\n * Returns an array containing all *phrases* from the list of terms that should be highlighted,\n * including both the user's phrases and phrases generated from stopwords.\n * @param {Array} terms\n * @param {Array} allStopwords\n * @return {Array}\n */\n function termsToPhrases(terms: string[], allStopwords: string[]): string[] {\n function doStack(mainTerm: string, stack: string[], forward: boolean): string[] {\n return stack.map((swTerm, i, swStack) => {\n let termArray = [];\n if (forward) {\n termArray = [mainTerm].concat(swStack.slice(0, swStack.length - i));\n } else {\n termArray = swStack.slice(i).concat([mainTerm]);\n }\n return termArray.join(' ');\n });\n }\n\n const result = terms.reduce((env, term) => {\n if (allStopwords.indexOf(term) !== -1) {\n env.stopwordStack.push(term);\n } else {\n if (env.stopwordStack.length) {\n if (env.previousMainTerm) {\n env.finalPhrases.push(...doStack(env.previousMainTerm, env.stopwordStack, true));\n }\n env.finalPhrases.push(...doStack(term, env.stopwordStack, false));\n // eslint-disable-next-line no-param-reassign\n env.stopwordStack = [];\n }\n // eslint-disable-next-line no-param-reassign\n env.previousMainTerm = term;\n }\n return env;\n }, {\n allStopwords,\n finalPhrases: [] as string[],\n previousMainTerm: '',\n stopwordStack: [] as string[],\n });\n if (result.stopwordStack.length && result.previousMainTerm) {\n result.finalPhrases.push(...doStack(result.previousMainTerm, result.stopwordStack, true));\n }\n return result.finalPhrases;\n }\n\n /**\n * The main function to use to parse a user query.\n * @param userQuery - The user query to parse.\n * @param allStopwords - An array of stopwords to ignore.\n * @param asPhrasesOnly - A boolean value indicating whether the search type\n * should be treated as a call number or not.\n * @returns An array of all terms to find (does not include stopwords).\n */\n // eslint-disable-next-line max-len\n function parseUserQuery(userQuery: string, allStopwords: string[], asPhrasesOnly: boolean): string[] {\n const qterms = queryToTerms(userQuery.toLowerCase(), allStopwords, asPhrasesOnly);\n if (asPhrasesOnly) {\n return qterms.phrasesOnly.length > 1 ? [qterms.phrasesOnly.join(' ')].concat(qterms.phrasesOnly) : qterms.phrasesOnly;\n }\n const phrases = [qterms.terms.join(' ')].concat(qterms.phrasesOnly).concat(termsToPhrases(qterms.terms, allStopwords));\n const justTerms = qterms.terms.filter((term) => allStopwords.indexOf(term) === -1);\n return [...new Set(phrases.concat(justTerms))];\n }\n\n // Example vars that may need to be changed. These are used in both methods.\n // Array of stopwords for demonstration purposes.\n const myStopwords = ['a', 'an', 'the', 'is', 'in', 'on', 'of', 'to', 'from', 'and'];\n\n /**\n * Converts a list of terms to a RegExp to pass to mark.js. It handles: diacritics,\n * internal word-delimiters (i.e., non-space punctuation within a word), and word-boundary\n * delimiters (any amount of punctuation or space between words).\n * @param {Array} punctuationArray\n * @param {Array} terms\n * @return {RegExp}\n */\n function termsToRegExp(terms: string[]): RegExp {\n const diacritics = [\n 'aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',\n 'cçćčCÇĆČ',\n 'dđďDĐĎ',\n 'eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',\n 'iìíỉĩịîïīIÌÍỈĨỊÎÏĪ',\n 'lłLŁ',\n 'nñňńNÑŇŃ',\n 'oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',\n 'rřRŘ',\n 'sšśșşSŠŚȘŞ',\n 'tťțţTŤȚŢ',\n 'uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',\n 'yýỳỷỹỵÿYÝỲỶỸỴŸ',\n 'zžżźZŽŻŹ',\n ];\n const internalPunctRe = '[\\\\p{P}]';\n const wordDelimitersRe = '[\\\\s\\\\p{P}]';\n const finalTermList = terms.map((term) => term.split(new RegExp(`${wordDelimitersRe}+`, 'u')).map((word) => word.split('').map((char) => {\n let charRe = char;\n diacritics.every((dct) => {\n if (dct.indexOf(char) !== -1) {\n charRe = `[${dct}]`;\n return false;\n }\n return true;\n });\n return charRe;\n }).filter((x) => !!x).join(`${internalPunctRe}*`))\n .filter((x) => !!x).join(`${wordDelimitersRe}*`))\n .filter((x) => !!x);\n return new RegExp(`(^|${wordDelimitersRe}+)(${finalTermList.join('|')})(?=(${wordDelimitersRe}+|$))`, 'iu');\n }\n\n function getSearchData() {\n const searchContextEl = document.getElementById('searchContext');\n if (!searchContextEl) return null;\n const { searchContext } = searchContextEl.dataset;\n if (!searchContext) return null;\n return JSON.parse(searchContext);\n }\n\n function regExpMark() {\n const searchData = getSearchData();\n if (!searchData || !searchData.q) return;\n const userQuery = searchData.q;\n const searchType = searchData.search_field;\n const numberSearchTypes = ['call_number', 'sudoc', 'standard_number', 'control_number'];\n const searchFields = ['call_numbers_display', 'sudocs_display', 'isbns_display',\n 'issns_display', 'other_standard_numbers_display', 'lccns_display', 'oclc_numbers_display',\n 'other_control_numbers_display'];\n let instance: Mark;\n let termList: string[];\n\n if (numberSearchTypes.includes(searchType)) {\n termList = parseUserQuery(userQuery, myStopwords, true);\n instance = new Mark(document.querySelectorAll(`${searchFields.map((field) => `.card.item-more_details .blacklight-${field}`).join(', ')}, #availabilityTable .blacklight-call-number.result__value`));\n } else {\n termList = parseUserQuery(userQuery, myStopwords, false);\n instance = new Mark(document.querySelectorAll('.card.item-more_details, #availabilityTable .blacklight-call-number.result__value'));\n }\n\n // Remove previous marked elements and mark new phrases and words\n instance.unmark({\n done() {\n /* Punctuation and spacing in the terms parsed from the user query are replaced with\n character classes that will match most punctuation and space, to give better\n highlighting/matching no matter what word delimiter is used in the query *and* the text.\n */\n const termRe = termsToRegExp(termList);\n instance.markRegExp(termRe, {\n className: 'markjs',\n exclude: ['.result__label'],\n ignoreGroups: 1,\n });\n },\n });\n }\n\n regExpMark();\n}\n\nexport {\n // eslint-disable-next-line import/prefer-default-export\n highlightSearchTerms,\n};\n","import { checkAvailability } from '../src/javascripts/_availability_table';\nimport {\n bindShowAvailMoreField, replaceBookCovers, hoverHierarchicalLinks,\n} from '../src/javascripts/_ui';\nimport { highlightSearchTerms } from '../src/javascripts/_highlight';\nimport {setDocHistory} from \"../src/javascripts/_history\";\n\ndocument.addEventListener('turbolinks:load', () => {\n checkAvailability();\n setDocHistory();\n bindShowAvailMoreField();\n highlightSearchTerms();\n replaceBookCovers();\n hoverHierarchicalLinks();\n});\n"],"sourceRoot":""}