{"version":3,"file":"main.9bdfd86c497f8ab8a138.js","mappings":"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","sources":["webpack://bento-box-ui/./src/from-www/assets/omni/scripts/search-dropdowns.js","webpack://bento-box-ui/./src/app/events.js","webpack://bento-box-ui/./src/app/utils.js","webpack://bento-box-ui/./src/app/models/bento-box.js","webpack://bento-box-ui/./src/app/config.js","webpack://bento-box-ui/./src/app/views/base.js","webpack://bento-box-ui/./src/app/views/search-form.js","webpack://bento-box-ui/./src/app/views/bento-box.js","webpack://bento-box-ui/./src/app/app.js","webpack://bento-box-ui/./src/fontawesome.js","webpack://bento-box-ui/./src/unt-init.js","webpack://bento-box-ui/./src/main.js"],"sourcesContent":["class SearchDropdown {\n  constructor(dropdownId, watchId, data) {\n    this.dropdownId = dropdownId;\n    this.watchId = watchId;\n    this.data = data;\n    this.initDropdown();\n    this.attachEventListeners();\n  }\n\n  initDropdown() {\n    const dropdownMenu = document.getElementById(this.dropdownId);\n    dropdownMenu.innerHTML = this.data.map(item => {\n      if (item.type === 'divider') {\n        return `<div class=\"dropdown-divider\"></div>`; // Bootstrap's class for dividers\n      } else {\n        return `\n          <button class=\"dropdown-item\" type=\"button\" data-url-template=\"${item.urlTemplate}\">\n            ${item.label}\n          </button>\n        `;\n      }\n    }).join('');\n  }\n\n\n  attachEventListeners() {\n    const dropdownMenu = document.getElementById(this.dropdownId);\n    dropdownMenu.addEventListener('click', (event) => {\n      if (event.target.classList.contains('dropdown-item')) {\n        event.preventDefault();\n        const urlTemplate = event.target.getAttribute('data-url-template');\n        const searchTerm = document.getElementById(this.watchId).value;\n        this.changeLocation(urlTemplate, searchTerm);\n      }\n    });\n  }\n\n  changeLocation(urlTemplate, searchTerm) {\n    const fullUrl = urlTemplate.replace('{query}', encodeURIComponent(searchTerm));\n    window.location.href = fullUrl;\n  }\n}\n\n/*** EXPORTS FROM exports-loader ***/\nexport {\n  SearchDropdown\n};\n","/* app/events.js\nBento Box App Event Bus Module\n*/\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\n\n\nexport default _.extend({}, Backbone.Events);\n","/* app/events.js\nBento Box Utils Module\n*/\n\nimport $ from 'jquery';\nimport _ from 'underscore';\nimport He from 'he';\nimport Masonry from 'masonry-layout';\n\n\n// Utility object for handling the Masonry layout\n// NOTE: For right now all updates to the layout simply regenerate the\n// masonry object. This is the way it must be done because re-rendering\n// bento box elements does not update them in place, it removes the old\n// one from the DOM and replaces it with a new one. When it does this, the\n// new elements are not part of the previously created Masonry object, so\n// calling 'masonry.layout()' does not update them. A whole new object\n// must be created that includes the new DOM elements.\nexport let layout = {\n  selector: '#masonryContainer',\n  jumpToElementId: null,\n\n  update: function() {\n    if ($(this.selector).length) {\n      this.masonry = new Masonry(this.selector, {\n        percentPosition: true,\n        horizontalOrder: true,\n        transitionDuration: 0\n      });\n    }\n  },\n\n  jumpToElement: function(elementId) {\n    if (elementId) {\n      this.jumpToElementId = elementId;\n    }\n    if (this.jumpToElementId) {\n      const jumpToElement = document.getElementById(this.jumpToElementId);\n      if (jumpToElement) {\n        jumpToElement.scrollIntoView();\n      }\n    }\n  },\n};\n\n// Utility function that translates a Discover resource type phrase\n// into font-awesome classes. It works by normalizing the resource type\n// (converting to lowercase, stripping ending parentheticals) and\n// breaking apart words. It uses the 'wordMap' structure to read words\n// recursively and then select the first thing that matches. The '_'\n// entry represents a stopping point, where it returns that set of FA\n// classes.\nexport function getTypeInfo(vars) {\n  let label = (\n    vars.format == 'Online' ? 'E-Journal' : (\n      vars.format == 'Print' ? 'Journal (Print/Paper)' : undefined\n    )\n  ) || vars.type || '';\n  let defaultCls = vars.externalLink ? 'fa fa-link' : 'fa fa-cube';\n  let words = label.replace(/\\s*\\(.*?\\)$/, '')\n    .toLowerCase()\n    .replace(/[^a-z0-9]/g, ' ')\n    .split(' ');\n  let wordsMap = {\n    'archival': {'_': 'fa fa-archive'},\n    'audio': {'_': 'fa fa-compact-disc'},\n    'book': {'_': 'fa fa-book'},\n    'computer': {\n      'program': {'_': 'fa fa-code'},\n    },\n    'digital': {\n      'file': {'_': 'fa fa-file'},\n      '_': 'fa fa-code',\n    },\n    'e': {'_': 'fa fa-tablet-android-alt'},\n    'filmstrip': {'_': 'fa fa-film'},\n    'game': {'_': 'fa fa-gamepad'},\n    'graphic': {'_': 'fa fa-images'},\n    'journal': {'_': 'fa fa-book'},\n    'map': {'_': 'fa fa-map'},\n    'manuscript': {'_': 'fa fa-archive'},\n    'motion': {'_': 'fa fa-film'},\n    'music': {\n      'score': {'_': 'fa fa-list-music'},\n      '_': 'fa fa-compact-disc',\n    },\n    'newspaper': {'_': 'fa fa-newspaper'},\n    'online': {\n      'database': {'_': 'fa fa-database'},\n    },\n    'slide': {'_': 'fa fa-film'},\n    'streaming': {\n      'audio': {'_': 'fa fa-cloud-music'},\n      'music': {'_': 'fa fa-cloud-music'},\n      'video': {'_': 'fa fa-video'},\n    },\n    'tabletop': {'_': 'fa fa-game-board'},\n    'thesis': {'_': 'fa fa-book'},\n    'video': {'_': 'fa fa-film'},\n  };\n  const _findClasses = function(mapping, words) {\n    const _search = function(mapping, words) {\n      let result = mapping[words[0]];\n      return result ? _search(result, words.slice(1)) : mapping['_'];\n    }\n    return words.length ? (_search(mapping, words) || _findClasses(mapping, words.slice(1))) : defaultCls;\n  }\n  return {label: label, faClasses: _findClasses(wordsMap, words)};\n}\n\n// Utility function that converts a string into an actual boolean value.\n// The default assumption is True.\nexport function strToBool(val) {\n  return !_.contains([null, undefined, 'f', 'false', 'F', 'FALSE', '0'], val);\n}\n\n// Utility function that prepares a query string for display, with all\n// appropriate decoding/encoding.\nexport function prepQueryForDisplay(q, truncate) {\n  truncate = truncate || 0;\n  if (q !== null) {\n    q = He.encode(decodeURI(q));\n    if (truncate > 0) {\n      let words = q.split(' ');\n      if (words.length > truncate) {\n        q = words.slice(0, truncate).join(' ') + ' ... ';\n      } else {\n        q = words.join(' ');\n      }\n    }\n  }\n  return q;\n}\n\n// Utility function that truncates a block of text based on numeric index\n// representing the point in the text at which truncation should occur. It tries\n// to find the first non-word character within 10 characters after that to truncate.\nexport function truncateText(text, truncatePoint) {\n  let i = truncatePoint;\n  while (text.charAt(i).match(/\\w/) && i <= i + 10) {\n    i++;\n  }\n  return text.substring(0, i) + ' ...';\n}\n","/* app/models/bento-box\nBento Box App Bento Box and derived models\n*/\n\nimport Backbone from 'backbone';\nimport He from 'he';\nimport EventChannel from '../events.js';\nimport * as Utils from '../utils.js';\nimport { brokenFormBaseUrl } from '../config.js';\n\n\n// Generic model for a BentoBox result.\nconst BentoBoxResult = Backbone.Model.extend({});\n\nconst BentoBox = Backbone.Collection.extend({\n  // Generic BentoBox model, representing any of the bento box spaces\n  // in our interface. Is a collection of BentoBoxResults.\n  model: BentoBoxResult,\n  totalCount: 0,\n  newSearchUrl: '',\n  fullResultsUrl: '',\n  url: '',\n\n  initialize: function(models, options) {\n    this.url = `${BBAPI_URL}${options.url}`;\n    this.type = options.type;\n    this.searchEnabled = true;\n    if (options.maxResults !== undefined) {\n      this.maxResults = options.maxResults;\n    } else {\n      this.maxResults = 5;\n    }\n    this.otherFields = [];\n    if (options.otherFields !== undefined) {\n      this.otherFields = options.otherFields;\n    }\n    this.otherFields.push('newSearchUrl', 'fullResultsUrl');\n    // NOTE: Now each collection is set to listen for the 'search' event\n    // in the views.BentoBoxView subview when that subview is initialized.\n    // This way if only certain boxes are requested, we refrain from\n    // requesting results from the invisible boxes.\n    // this.listenTo(EventChannel, 'search', this.doSearch);\n  },\n\n  parse: function(response, options) {\n    for (const field of this.otherFields) {\n      if (response[field] !== undefined) {\n        let value = response[field];\n        if (value !== null && (field == 'newSearchUrl' || field == 'fullResultUrl')) {\n          value = He.encode(value);\n        }\n        this[field] = value;\n      }\n    }\n    this.totalCount = response.results === null ? 0 : response.results.length;\n    let returnResults = response.results;\n\n    // For articles results, we want to build needed URL for reporting broken\n    // links and attach this to the model.\n    if (this.type == 'articles' && returnResults !== null) {\n      for (let r of returnResults) {\n        let pstring = Object.entries({\n          article_title: r.title,\n          article_authors: r.authorList,\n          publication: `${(r.issn !== null ? `ISSN: ${r.issn};` : '')}${r.citation}`,\n          journal_title: r.journalTitle,\n          issn: r.issn,\n          date: r.date,\n          volume: r.volume,\n          issue: r.issue,\n          pages: r.startPage || r.numPages,\n          content_type: r.type,\n          url: `https:${r.link}`,\n          results_url: this.fullResultsUrl,\n        })\n        .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n        .join('&');\n        r['brokenLinkUrl'] = `${brokenFormBaseUrl}?${pstring}`\n      }\n    }\n    return returnResults;\n  },\n\n  disableSearch: function() {\n    this.searchEnabled = false;\n  },\n\n  doSearch: function(vars) {\n    // Reset all additional fields on the collection before searching\n    for (const field of this.otherFields) {\n      delete(this[field]);\n    }\n    delete(this.totalCount);\n    if (this.searchEnabled) {\n      this.fetch({\n        data: {\n          'search': vars.q,\n          'limit': this.maxResults\n        },\n        success: function(model) {\n          EventChannel.trigger(\n            `bento-box-collection-success:${model.type}`,\n            vars\n          );\n        },\n        error: function(model) {\n          EventChannel.trigger(\n            `bento-box-collection-error:${model.type}`,\n            vars\n          );\n        }\n      });\n    }\n  },\n\n});\n\n\nexport {\n  BentoBoxResult as model,\n  BentoBox as collection\n};\n","/* app/config.js\nBento Box App Configuration and Settings\n*/\n\nimport _ from 'underscore';\nimport * as BentoBoxModels from './models/bento-box.js';\nimport EventChannel from './events.js';\nimport * as Utils from './utils.js';\nimport bentoBoxTemplate from '../templates/content/box.html';\nimport librarianBoxTemplate from '../templates/content/librarian-box.html';\nimport boxDisabledTemplate from '../templates/content/box-parts/disabled-message.html';\nimport boxErrorTemplate from '../templates/content/box-parts/error-message.html';\nimport boxLoadingTemplate from '../templates/content/box-parts/loading-message.html';\nimport boxNoResultsTemplate from '../templates/content/box-parts/no-results-message.html';\nimport newSearchButtonTemplate from '../templates/content/box-parts/new-search-button.html';\nimport moreResultsButtonTemplate from '../templates/content/box-parts/more-results-button.html';\nimport resultContainerTemplate from '../templates/content/box-parts/result-container.html';\nimport librarianHelpMessageTemplate from '../templates/content/box-parts/librarian-help-message.html';\nimport articleTemplate from '../templates/content/results/article.html';\nimport booksAndMoreTemplate from '../templates/content/results/books-and-more.html';\nimport databaseTemplate from '../templates/content/results/database.html';\nimport journalTemplate from '../templates/content/results/journal.html';\nimport referenceWorkTemplate from '../templates/content/results/reference-work.html';\nimport websiteTemplate from '../templates/content/results/website.html';\nimport guideTemplate from '../templates/content/results/guide.html';\nimport librarianTemplate from '../templates/content/results/librarian.html';\nimport digitalLibraryTemplate from '../templates/content/results/digital-library.html';\nimport courseTemplate from '../templates/content/results/course.html';\n\n\n// Start with miscellaneous constants.\n// Base URL for the report broken link form\nconst brokenFormBaseUrl = 'https://unt.az1.qualtrics.com/jfe/form/SV_bdw4fydzCuTGPDD';\n// Maximum length for various fields (in characters). Fields with\n// more than this number of characters get truncated.\nconst maxSummaryLength = 200;\nconst maxTitleLength = 200;\n// Point at which truncation happens, if the field is longer than maxSummaryLength.\n// Note that text is truncated at word boundaries, so it may be a little longer\n// than this value in reality.\nconst summaryTruncatePoint = 175;\nconst titleTruncatePoint = 175;\n\n// Keep track of whether we're displaying in 1-column, 2-column, or 3-column\n// format.\nfunction getWindowCols() {\n  if (window.innerWidth < 768) {\n    return 'col1'\n  }\n  if (window.innerWidth < 992) {\n    return 'col2'\n  }\n  return 'col3'\n};\n\nlet windowCols = getWindowCols();\nwindow.addEventListener('resize', function(event) {\n  let new_cols = getWindowCols();\n  if (new_cols != windowCols) {\n    windowCols = new_cols;\n    EventChannel.trigger('changed-columns', windowCols);\n  }\n});\n\n\n// Parse URL querystring and provide urlParams object for getting (and making)\n// various versions of each possible parameter. This object must be initialized\n// on each search.\nconst urlParams = {\n  validKeys: ['q', 'boxes', 'includeAll'],\n  q: {\n    _getEncoded: function(val) {\n      return encodeURIComponent(val).replace(/%20/g, '+');\n    },\n  },\n  boxes: {\n    _getParsed: function(val) {\n      return val ? val.split(',') : val;\n    },\n  },\n  includeAll: {\n    _getParsed: function(val) {\n      return Utils.strToBool(val);\n    },\n    _getQSParam: function(val) {\n      return val ? `includeAll=${val}` : 'includeAll';\n    },\n  },\n  initialize: function() {\n    let rawSP = new URLSearchParams(window.location.search);\n    for (let i=0; i<this.validKeys.length; i++) {\n      let key = this.validKeys[i];\n      this[key].raw = rawSP.get(key);\n      this[key].encoded = this.getEncoded(key);\n      this[key].parsed = this.getParsed(key);\n    }\n  },\n  getParsed: function(key, val) {\n    let what = this[key];\n    val = val === undefined ? what.raw : val;\n    if (what._getParsed !== undefined) {\n      return what._getParsed(val);\n    }\n    return val;\n  },\n  getEncoded: function(key, val) {\n    let what = this[key];\n    val = val === undefined ? what.raw : val;\n    if (val !== null && val !== undefined) {\n      if (what._getEncoded !== undefined) {\n        return what._getEncoded(val);\n      }\n      return encodeURIComponent(val);\n    }\n  },\n  getQSParam: function(key, val) {\n    let what = this[key];\n    val = this.getEncoded(key, val);\n    if (val !== null && val !== undefined) {\n      if (what._getQSParam !== undefined) {\n        return what._getQSParam(val);\n      }\n      return `${key}=${val}`;\n    }\n  },\n  getQS: function(overrides) {\n    let newQPs = [];\n    for (let i=0; i<this.validKeys.length; i++) {\n      let key = this.validKeys[i];\n      let param = this.getQSParam(key, overrides[key]);\n      if (param) {\n        newQPs.push(param);\n      }\n    }\n    let newQS = newQPs.join('&');\n    return newQS ? `?${newQS}` : '';\n  }\n};\n\n\n// Function that detects whether this is a mobile device.\n// (Adapted from detectmobilebrowsers.com)\n\nfunction isMobile() {\n  const fullRegex = /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i;\n  const abbrevRegex = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i;\n  const userAgent = navigator.userAgent || navigator.vendor || window.opera;\n  return fullRegex.test(userAgent) || abbrevRegex.test(userAgent.substr(0,4));\n}\n\n/* boxStates -- a one-off object that defines and initializes templates\n * representing different states a bento box might find itself in. The\n * 'box' arg used throughout should be a single 'boxes' entry, like\n * boxes.articles or boxes.guides. */\nconst boxStates = {\n  disabled: {\n    infoMessage: (vars, box) => '',\n    stateMessage: (vars, box) => box.templates.disabledMessage(vars),\n  },\n  error: {\n    infoMessage: (vars, box) => '',\n    stateMessage: (vars, box) => box.templates.errorMessage(vars),\n  },\n  loading: {\n    infoMessage: (vars, box) => '',\n    stateMessage: (vars, box) => box.templates.loadingMessage(vars),\n  },\n  noResults: {\n    infoMessage: (vars, box) => '',\n    stateMessage: (vars, box) => box.templates.noResultsMessage(vars),\n    needsButtons: {\n      new: ['main'],\n    },\n  },\n  results: {\n    infoMessage: (vars, box) => box.templates.infoMessage(vars),\n    stateMessage: (vars, box) => '',\n    needsButtons: {\n      new: ['header', 'main'],\n      more: ['header', 'main'],\n    },\n  },\n  getResultState: function(box) {\n    return box.collection.totalCount > 0 ? this.results : this.noResults;\n  },\n  getStartingState: function(box) {\n    return box.searchEnabled ? this.loading : this.disabled;\n  },\n  makeButtons: function(templates, urls, labels, state) {\n    let buttons = {more: {header: '', main: ''}, new: {header: '', main: ''}};\n    if (state.needsButtons) {\n      for (const bType of ['new', 'more']) {\n        if (templates[bType] && urls[bType] && state.needsButtons[bType]) {\n          for (const bLoc of state.needsButtons[bType]) {\n            buttons[bType][bLoc] = templates[bType](\n              {url: urls[bType], label: labels[bType], includeText: bLoc == 'main'}\n            )\n          }\n        }\n      }\n    }\n    return buttons;\n  },\n}\n\n/* The boxes obj stores configuration data for each of our bento boxes.\n * Note: set searchEnabled to false if you want to disable the AJAX search for a\n * given box, e.g. if whatever component powers that search is down or offline temporarily\n * and you don't want to fill up your logs with errors. */\nconst boxDefaults = {\n  searchEnabled: true,\n  fullResultsLabel: '',\n  newSearchLabel: '',\n  defaultNewSearchUrl: '',\n  templates: {\n    boxContainer: _.template(bentoBoxTemplate),\n    disabledMessage: _.template(boxDisabledTemplate),\n    errorMessage: _.template(boxErrorTemplate),\n    loadingMessage: _.template(boxLoadingTemplate),\n    noResultsMessage: _.template(boxNoResultsTemplate),\n    infoMessage: _.template(''),\n    newSearchButton: _.template(newSearchButtonTemplate),\n    moreResultsButton: _.template(moreResultsButtonTemplate),\n    resultContainer: _.template(resultContainerTemplate),\n    result: _.template(''),\n  },\n  state: boxStates.loading,\n};\n\nconst boxes = {\n  articles: _.extend({}, boxDefaults, {\n    label: 'Articles',\n    code: 'articles',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'articles',\n        'url': '/articles/',\n        'otherFields': ['bestBet', 'didYouMean']\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: articleTemplate}),\n    fullResultsLabel: 'See more results about %QUERY% in the Find Articles system.',\n    newSearchLabel: 'Start a new search in the Find Articles system.',\n    defaultNewSearchUrl: 'https://untexas.summon.serialssolutions.com/#!/advanced',\n  }),\n  guides: _.extend({}, boxDefaults, {\n    label: 'Guides',\n    code: 'guides',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'guides',\n        'url': '/guides/',\n        'otherFields': ['librarian']\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: guideTemplate}),\n    fullResultsLabel: 'See more results about %QUERY% in the Subject &amp; Course ' +\n                      'Guides system.',\n    newSearchLabel: 'Start a new search in the Subject and Course Guides system.',\n    defaultNewSearchUrl: 'https://guides.library.unt.edu',\n    defaultFullResultsUrl: 'https://guides.library.unt.edu/srch.php?q=%QUERY%',\n  }),\n  databases: _.extend({}, boxDefaults, {\n    label: 'Databases',\n    code: 'databases',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'databases',\n        'url': '/databases/'\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: databaseTemplate}),\n    fullResultsLabel: 'See more results about %QUERY% in the Databases A-Z list.',\n    newSearchLabel: 'Start a new search in the Databases A-Z list.',\n    defaultNewSearchUrl: 'https://guides.library.unt.edu/az.php',\n    defaultFullResultsUrl: 'https://guides.library.unt.edu/az.php?q=%QUERY%',\n  }),\n  courses: _.extend({}, boxDefaults, {\n    label: 'Course Reserves',\n    code: 'courses',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'courses',\n        'url': '/courses/',\n        'otherFields': ['exactMatches']\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: courseTemplate}),\n    fullResultsLabel: 'See more courses results in the Course Reserves system.',\n    newSearchLabel: 'Start a new Course Reserves search.',\n    defaultNewSearchUrl: 'https://iii.library.unt.edu/search/r',\n    defaultFullResultsUrl: 'https://iii.library.unt.edu/search/r?SEARCH=%QUERY%',\n  }),\n  referenceWorks: _.extend({}, boxDefaults, {\n    label: 'Background Materials',\n    code: 'referenceWorks',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'reference-works',\n        'url': '/reference-works/'\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: referenceWorkTemplate}),\n    fullResultsLabel: 'See more results for background materials about %QUERY% ' +\n                      'in the Summon system.',\n    newSearchLabel: 'Start a new search in the Summon system.',\n    defaultNewSearchUrl: 'https://untexas.summon.serialssolutions.com/#!/advanced',\n  }),\n  journals: _.extend({}, boxDefaults, {\n    searchEnabled: true,\n    label: 'Journals',\n    code: 'journals',\n    collection: new BentoBoxModels.collection(\n      [], {\n        'type': 'journals',\n        'url': '/journals/',\n        'maxResults': 10\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: journalTemplate}),\n    fullResultsLabel: 'See more results for journals about %QUERY% in the Discover Catalog.',\n    newSearchLabel: 'Start a new search for Journals in the Discover Catalog.',\n    defaultNewSearchUrl: 'https://discover.library.unt.edu/' +\n                         '?f%5Bresource_type_facet%5D%5B%5D=journals_periodicals',\n    defaultFullResultsUrl: 'https://discover.library.unt.edu/' +\n                           '?f%5Bresource_type_facet%5D%5B%5D=journals_periodicals' +\n                           '&q=%QUERY%',\n  }),\n  digitalLibrary: _.extend({}, boxDefaults, {\n    label: 'Digital Collections',\n    code: 'digitalLibrary',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'digital-library',\n        'url': '/digital-library/'\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: digitalLibraryTemplate}),\n    fullResultsLabel: 'See more results about %QUERY% from the UNT Digital Collections.',\n    newSearchLabel: 'Start a new UNT Digital Collections search.',\n    defaultNewSearchUrl: 'https://digital.library.unt.edu',\n  }),\n  booksAndMore: _.extend({}, boxDefaults, {\n    label: 'Books & More',\n    code: 'booksAndMore',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'booksAndMore',\n        'url': '/books-and-more-solr/'\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {result: booksAndMoreTemplate}),\n    fullResultsLabel: 'See more results about %QUERY% in the Discover Catalog of ' +\n                      'Books &amp; More.',\n    newSearchLabel: 'Start a new search in the Discover Catalog of Books &amp; More.',\n    defaultNewSearchUrl: 'https://discover.library.unt.edu',\n  }),\n  librarian: _.extend({}, boxDefaults, {\n    label: 'Need Research Help?',\n    code: 'librarian',\n    collection: new BentoBoxModels.collection(\n      [],\n      {\n        'type': 'librarian',\n        'url': '/librarians/',\n        'maxResults': 1\n      }\n    ),\n    templates: _.extend({}, boxDefaults.templates, {\n      boxContainer: _.template(librarianBoxTemplate),\n      errorMessage: _.template(librarianHelpMessageTemplate),\n      infoMessage: _.template(librarianHelpMessageTemplate),\n      noResultsMessage: _.template(librarianHelpMessageTemplate),\n      resultContainer: _.template('<span></span>'),\n      result: librarianTemplate\n    }),\n  }),\n\n  initResultNavItems: function(whichBoxes) {\n    return whichBoxes.map((box) => new Object({\n      url: `#${box.code}`,\n      label: box.label\n    }));\n  },\n\n  initDefaultNavItems: function(whichBoxes) {\n    return whichBoxes.map((box) => new Object({\n      url: box.defaultNewSearchUrl,\n      label: box.label\n    }));\n  },\n};\n\n// Boxes we no longer display but may still need components for go here.\nconst defunctBoxes = {\n  website: {\n    searchEnabled: true,\n    label: 'Library Website',\n    code: 'website',\n    // collection: new BentoBoxModels.collection([], {'type': 'website', 'url': '/website/'}),\n    template: websiteTemplate,\n    fullResultsLabel: 'See all library website search results for %QUERY% ...',\n    newSearchLabel: 'Start new library website search',\n    bottomLinkType: 'fullResults',\n    defaultNewSearchUrl: 'https://library.unt.edu/search/google/',\n  },\n}\n\n\n// Object to control dynamic display of all bento boxes (including the nav bar and results\n// display). Configure the default box order for nav and 1, 2, and 3-column displays via\n// 'defaults'. Then you can use the 'do' method and pass an array of box names and an\n// 'includeAll' boolean to get the requested box config objects in the order requested.\nconst boxesDisplay = {\n  defaults: {\n    nav: [\n      boxes.articles, boxes.booksAndMore, boxes.journals, boxes.databases,\n      boxes.digitalLibrary, boxes.courses, boxes.guides, boxes.referenceWorks\n    ],\n    col1: [\n      boxes.articles, boxes.booksAndMore, boxes.journals, boxes.databases,\n      boxes.digitalLibrary, boxes.courses, boxes.guides, boxes.librarian,\n      boxes.referenceWorks\n    ],\n    col2: [\n      boxes.articles, boxes.booksAndMore, boxes.journals, boxes.databases,\n      boxes.digitalLibrary, boxes.courses, boxes.librarian, boxes.guides,\n      boxes.referenceWorks\n    ],\n    col3: [\n      boxes.articles, boxes.booksAndMore, boxes.journals, boxes.digitalLibrary,\n      boxes.databases, boxes.courses, boxes.referenceWorks, boxes.librarian,\n      boxes.guides\n    ]\n  },\n  do: function(reqBoxNames, includeAll) {\n    let reqBoxes = [];\n    let displayBoxes = _.clone(this.defaults);\n    if (reqBoxNames) {\n      let allBoxes = _.clone(boxes);\n      if (includeAll) {\n        reqBoxNames = reqBoxNames.concat(_.map(\n          this.defaults.col3,\n          function(item) { return item.code }\n        ));\n      }\n      for (let i=0; i<reqBoxNames.length; i++) {\n        let reqBox = allBoxes[reqBoxNames[i]];\n        if (reqBox !== undefined) {\n          reqBoxes.push(reqBox);\n          delete(allBoxes[reqBoxNames[i]]);\n        }\n      }\n    }\n    if (reqBoxes.length) {\n      displayBoxes.nav = reqBoxes;\n      displayBoxes.col1 = reqBoxes;\n      displayBoxes.col2 = reqBoxes;\n      displayBoxes.col3 = reqBoxes;\n    }\n    return displayBoxes;\n  }\n};\n\n\n// booksAndMoreMatTypes translates material types to HTML elements (labels, images, etc.)\nconst booksAndMoreMatTypes = {\n  'BOOKS': '<span class=\"type\">Book</span>',\n  'EBOOKS': '<span class=\"type\">EBook</span>',\n  'MUSIC SCORES': '<span class=\"type\">Music Score</span>'\n  // ... etc.\n};\n\n\n// otherSearchesLinks stores data for the links that appear at the very bottom\n// of the page, for Other Searches. Note the array of arrays, indicating\n// organization into columns.\nfunction getOtherSearchesLinks(query) {\n  return [\n    [\n      {\n        url: `https://search.unt.edu/s/search.html?query=${query}` + \n             '&f.Tabs%7Cuni-nt-web=Website&collection=uni-nt-search' +\n             '&scope=library.unt.edu,-guides.library.unt.edu,-blogs.library.unt.edu,' +\n             '-guides.library.unt.edu,-archives.library.unt.edu,-hoc.library.unt.edu,' +\n             '-journals.library.unt.edu,-openbooks.library.unt.edu,-omeka.library.unt.edu',\n        label: 'UNT Libraries Website'\n      },\n      {\n        url: 'https://discover.library.unt.edu/' +\n             `?f%5Bcollection_facet%5D%5B%5D=Music+Library&q=${query}`,\n        label: 'Music Library Collection'\n      },\n      {\n        url: 'https://discover.library.unt.edu/' +\n             `?f%5Bcollection_facet%5D%5B%5D=Media+Library&q=${query}`,\n        label: 'Media Library Collection'\n      },\n    ], [\n      {\n        url: 'https://archives.library.unt.edu/search' +\n             `?utf8=%E2%9C%93&op%5B%5D=&q%5B%5D=${query}&commit=Search`,\n        label: 'Special Collections'\n      },\n      {\n        url: 'https://untexas.summon.serialssolutions.com/search' +\n             `?s.q=${query}&s.fvf%5B%5D=ContentType%2CNewspaper%20Article%2Cf`,\n        label: 'Newspaper Articles'\n      },\n      {\n        url: 'https://untexas.summon.serialssolutions.com/search' +\n             `?s.q=${query}&s.fvf%5B%5D=ContentType%2CBook%20Review%2Cf`,\n        label: 'Book Reviews'\n      },\n    ], [\n      {\n        url: 'https://untexas.summon.serialssolutions.com/search' +\n             `?s.q=${query}&s.fvf%5B%5D=ContentType%2CMagazine%20Article%2Cf`,\n        label: 'Magazine Articles'\n      },\n      {\n        url: 'https://untexas.summon.serialssolutions.com/search' +\n             `?s.q=${query}&s.fvf%5B%5D=ContentType%2CBook%20Chapter%2Cf`,\n        label: 'Book Chapters'\n      },\n      {\n        url: 'https://untexas.summon.serialssolutions.com/search' +\n             `?s.q=${query}&s.fvf%5B%5D=ContentType%2CReport%2Cf`,\n        label: 'Reports'\n      },\n    ], [\n      {\n        url: `https://researchworks.oclc.org/archivegrid/?q=${query}&ft=1`,\n        label: 'ArchiveGrid'\n      },\n      {\n        url: `https://www.worldcat.org/search?q=${query}&qt=worldcat_org_all`,\n        label: 'WorldCat'\n      },\n      {\n        url: `https://scholar.google.com/scholar?q=${query}`,\n        label: 'Google Scholar'\n      }\n    ],\n  ]\n};\n\n\nexport {\n  brokenFormBaseUrl,\n  isMobile,\n  getWindowCols,\n  urlParams,\n  boxes,\n  boxesDisplay,\n  boxStates,\n  booksAndMoreMatTypes,\n  getOtherSearchesLinks as otherSearchesLinks,\n  maxSummaryLength,\n  summaryTruncatePoint,\n  maxTitleLength,\n  titleTruncatePoint\n};\n","/* app/views/base.js\nBase Views for the Bento Box App:\nAll views in the app should inherit from BaseView, which adds a handful\nof convenience methods for controlling view display and state.\nContainerView is for views that contain child subviews.\n*/\n\nimport Backbone from 'backbone';\nimport EventChannel from '../events.js';\nimport $ from 'jquery';\n\n\n/* BaseView -- All views in the app should inherit from this. It allows\n * a controller to activate (show) and deactivate (hide) the view, and\n * provides a 'reset' method for resetting state. */\nconst BaseView = Backbone.View.extend({\n  /* set 'renderEventLabel' in your subclass if you want an event\n   * triggered when rendering is complete */\n  renderEventLabel: null,\n\n  reset: function(view) {\n    /* Subclasses should implement this method to reset state. */\n    return true;\n  },\n\n  activate: function(vars, view) {\n    /* Method for showing the view once it's been rendered. */\n    (view || this).render(vars).$el.show();\n  },\n\n  deactivate: function(view) {\n    /* Method for deactivating the view. */\n    view = view || this;\n    view.$el.hide();\n    view.reset();\n  },\n\n  isNeeded: function(vars, view) {\n    /* Subclasses may implement this method to use the given vars to\n     * determine whether this view needs to be used or activated in a\n     * given context. */\n    return true;\n  },\n\n  triggerRenderEvent: function(vars, view) {\n    /* Method that triggers the rendering event notification. */\n    view = view || this;\n    EventChannel.trigger(view.renderEventLabel, vars);\n  },\n\n  prepVars: function(vars) {\n    /* Subclasses should implement this method to compile whatever data\n     * is needed for 'vars' that are fed to the view template during\n     * rendering. */\n    return vars;\n  },\n\n  prepContainer: function(vars, container, view)  {\n    /* Subclasses may implement this method if any prep steps need to \n     * be done on the view container just before it is appended to $el,\n     * during rendering. */\n    return container;\n  },\n\n  render: function(vars, view) {\n    /* Default generalized implementation of 'render' -- subclasses may\n     * want to override this, but it is designed such that they can use\n     * prepVars and prepContainer, as needed, instead. */\n    view = view || this;\n    vars = view.prepVars(vars);\n    let container = $(view.template(vars));\n    view.$el.empty().append(view.prepContainer(vars, container));\n    if (view.renderEventLabel) {\n      view.triggerRenderEvent(vars);\n    }\n    return this;\n  },\n});\n\n\n/* ContainerView -- Views that contain other views as subviews or\n * children should subclass this. */\nconst ContainerView = BaseView.extend({\n  subViews: [],\n\n  reset: function(view) {\n    view = view || this;\n    view.subViews.forEach((subView) => subView.reset());\n    view.clearSubViews();\n  },\n\n  clearSubViews: function(view) {\n    view = view || this;\n    view.subViews.forEach((subView) => subView.remove());\n    view.subViews = [];\n  },\n\n  initSubViews: function(vars) {\n    /* Subclasses must implement this. It should initialize applicable\n     * subView objects based on provided vars and return them as an\n     * array. */\n    return [];\n  },\n\n  getSubViewHook: function(vars, subView, container) {\n    /* Subclasses must implement this method to return the element to\n     * hook a given subview onto. You may, for example, create a new\n     * element, attach it to the container, and then return that\n     * element. */\n    return container;\n  },\n\n  prepContainer: function(vars, container, view) {\n    /* Subclasses may override this, but it's designed such that they\n     * can use initSubViews and getSubViewHook, as needed, instead. */\n    view = view || this;\n    view.clearSubViews();\n    view.subViews = view.initSubViews(vars);\n    view.subViews.forEach((subView) => {\n      subView.setElement(view.getSubViewHook(vars, subView, container)).render(vars);\n    });\n    return container;\n  },\n});\n\n\nexport {\n  BaseView,\n  ContainerView,\n};\n","/* app/views/search-form.js\nBento Box App Search Form View\n*/\n\nimport $ from 'jquery';\nimport _ from 'underscore';\nimport EventChannel from '../events.js';\nimport * as Config from '../config.js';\nimport * as Utils from '../utils.js';\nimport searchTemplate from '../../templates/search.html';\nimport navbarTemplate from '../../templates/navbar.html';\nimport { BaseView, ContainerView } from './base.js';\n\n\nconst Search = BaseView.extend({\n  template: _.template(searchTemplate),\n  selectors: {\n    'searchInput': '#search-form input',\n    'didYouMean': '.didYouMean',\n    'didYouMeanTerm': '.didYouMean .term', \n  },\n  events: {\n    'submit #search-form': 'submitSearch',\n  },\n  \n  initialize: function(options) {\n    this.listenTo(\n      EventChannel,\n      'bento-box-collection-success:articles',\n      this.renderDidYouMean\n    );\n  },\n\n  render: function(vars) {\n    let container = $(this.template(vars));\n    this.$el.empty().append(container);\n    return this;\n  },\n\n  submitSearch: function(ev) {\n    ev.preventDefault();\n    EventChannel.trigger('searchform:search', this.getFormVars());\n  },\n  \n  getFormVars: function() {\n    return {q: this.$el.find(this.selectors.searchInput).val()};\n  },\n\n  renderDidYouMean: function(vars) {\n    let articlesColl = Config.boxes.articles.collection;\n    if (articlesColl.didYouMean !== null) {\n      EventChannel.trigger('spelling-suggestion-rendered', {q: vars.qDisplay});\n      let term = articlesColl.didYouMean[0];\n      this.$el.find(this.selectors.didYouMeanTerm).html(\n        `<a class=\"text-warning\" href=\"?q=${encodeURIComponent(term)}\">${term}</a>`\n      );\n      this.$el.find(this.selectors.didYouMean).removeClass('d-none');\n    }\n  },\n});\n\nconst Nav = BaseView.extend({\n  template: _.template(navbarTemplate),\n\n  render: function(vars) {\n    let container = $(this.template(vars));\n    this.$el.empty().append(container);\n    return this;\n  },\n});\n\n\nexport {\n  Nav,\n  Search,\n};\n","/* app/views/bento-box.js\nBento Box App Bento Box Views\n*/\n\nimport $ from 'jquery';\nimport _ from 'underscore';\nimport * as Bootstrap from 'bootstrap';\nimport ImagesLoaded from 'imagesloaded';\nimport EventChannel from '../events.js';\nimport * as Config from '../config.js';\nimport * as Utils from '../utils.js';\nimport defaultContentTemplate from '../../templates/content/default.html';\nimport bestBetTemplate from '../../templates/content/best-bet.html';\nimport exactCourseTemplate from '../../templates/content/exact-course.html';\nimport bottomLinksTemplate from '../../templates/content/bottom-links.html';\nimport boxesContainerTemplate from '../../templates/content/boxes-container.html';\nimport boxContainerTemplate from '../../templates/content/box-container.html';\nimport { BaseView, ContainerView } from './base.js';\n\n\nfunction selectBox(selectedId) {\n  /* Toggles classes to \"select\" only the bento box with the given id. */\n  const sbClasses = 'text-bg-warning bg-opacity-10';\n  $('.bento-box-inner').removeClass(sbClasses);\n  if (selectedId) {\n    $(`#${selectedId}`).addClass(sbClasses);\n  }\n}\n\n\nconst Default = BaseView.extend({\n  /* The default content view that displays before you've searched. */\n  template: _.template(defaultContentTemplate),\n  renderEventLabel: 'bento-box-layout-rendered',\n});\n\n\nconst BestBet = BaseView.extend({\n  /* Displays only if Articles returns a best bet. */\n  template: _.template(bestBetTemplate),\n  collection: Config.boxes.articles.collection,\n  renderEventLabel: 'best-bet-rendered',\n\n  isNeeded: function(vars) {\n    return Boolean(this.collection.bestBet);\n  },\n\n  prepVars: function(vars) {\n    return _.extend({}, vars, {\n      bestBet: this.collection.bestBet,\n    });\n  },\n});\n\n\nconst ExactCourse = BaseView.extend({\n  /* Displays only if Courses returns an exact course match. */\n  template: _.template(exactCourseTemplate),\n  collection: Config.boxes.courses.collection,\n\n  isNeeded: function(vars) {\n    return Boolean(this.collection.exactMatches);\n  },\n\n  prepVars: function(vars) {\n    let exactMatch = this.collection.exactMatches[0];\n    return _.extend({}, vars, {\n      courseUrl: exactMatch.courseUrl,\n      course: exactMatch.course,\n      sections: exactMatch.sections.map(\n        (sec) => `<a href=\"${sec.url}\">${sec.instructor || \"All Instructors\"}</a>`\n      ).join(', '),\n    });\n  },\n});\n\n\nconst BottomLinks = BaseView.extend({\n  /* View for \"other searches\" links at the bottom of the screen. */\n  template: _.template(bottomLinksTemplate),\n  identifier: 'other-searches',\n  renderEventLabel: 'bento-box-rendered',\n\n  prepVars: function(vars) {\n    return _.extend(vars, {\n      bottomLinks: Config.otherSearchesLinks(vars.qEncoded),\n      boxId: this.identifier,\n    });\n  }\n});\n\n\nconst BoxesContainer = ContainerView.extend({\n  /* Container view for the bento boxes display. It controls which\n   * boxes appear and their layout. */\n  template: _.template(boxesContainerTemplate),\n  boxContainer: _.template(boxContainerTemplate),\n  subViewHook: '.bento-box-outer',\n  renderEventLabel: 'bento-box-layout-rendered',\n  boxPicker: Config.boxesDisplay,\n  getWindowCols: Config.getWindowCols,\n  columnClasses: {\n    1: 'col-lg-12',\n    2: 'col-lg-6',\n    'default': 'col-md-6 col-lg-4',\n  },\n\n  initialize: function(options) {\n    this.boxLayouts = {};\n    this.currentLayout = {};\n    this.listenTo(EventChannel, 'changed-columns', this.reOrderBoxes);\n  },\n\n  initBoxes: function(boxNames, includeAll) {\n    this.boxLayouts = this.boxPicker.do(boxNames, includeAll);\n  },\n\n  setBoxLayout: function() {\n    const boxes = this.boxLayouts[this.getWindowCols()];\n    const columnClass = this.columnClasses[boxes.length];\n    this.currentLayout = {\n      boxes: boxes,\n      columnClass: columnClass || this.columnClasses.default\n    };\n  },\n\n  initSubViews: function(vars) {\n    this.setBoxLayout();\n    return this.currentLayout.boxes.map((box) => new BentoBox(box));\n  },\n\n  reOrderBoxes: function() {\n    this.render(this.vars);\n  },\n\n  prepVars: function(vars) {\n    this.query = vars.qDisplay;\n    this.vars = vars;\n    return vars;\n  },\n\n  getSubViewHook: function(vars, subView, container) {\n    let subContainer = $(this.boxContainer({columnClass: this.currentLayout.columnClass}));\n    container.append(subContainer);\n    return subContainer.find(this.subViewHook);\n  },\n\n});\n\n\nconst BentoBox = ContainerView.extend({\n  /* View for one bento box, which contains children views for results. */\n  renderEventLabel: 'bento-box-rendered',\n  subViewContainerHook: '.results .results-list',\n  states: Config.boxStates,\n\n  initialize: function(options) {\n    this.box = options;\n    this.identifier = this.box.code;\n    this.template = this.box.templates.boxContainer;\n    this.collection = this.box.collection;\n    this.collection.listenTo(EventChannel, 'search', this.collection.doSearch); \n    if (!this.box.searchEnabled) {\n      this.collection.disableSearch();\n    }\n    this.listenTo(\n      EventChannel,\n      `bento-box-collection-success:${this.collection.type}`,\n      (vars) => {\n        this.box.state = this.states.getResultState(this.box);\n        this.activate(vars);\n      },\n    );\n    this.listenTo(\n      EventChannel,\n      `bento-box-collection-error:${this.collection.type}`,\n      (vars) => {\n        this.box.state = this.states.error;\n        this.activate(vars);\n      },\n    );\n  },\n\n  reset: function() {\n    this.box.state = this.states.getStartingState(this.box);\n    ContainerView.prototype.reset(this);\n  },\n\n  initSubViews: function(vars) {\n    if (this.box.state == this.states.results) {\n      return this.collection.models.map((model, i) => new Result({\n        label: this.box.label,\n        model: model,\n        template: this.box.templates.result,\n        identifier: `${this.identifier}${i}`,\n      }));\n    }\n    return [];\n  },\n\n  prepVars: function(vars) {\n    const trunc = this.identifier == 'librarian' && this.box.state === this.states.results ? 3 : 0;\n    const qDisp = Utils.prepQueryForDisplay(vars.q, trunc);\n    const newUrl = this.collection.newSearchUrl || this.box.defaultNewSearchUrl || '';\n    let moreUrl = this.collection.fullResultsUrl || this.box.defaultFullResultsUrl || '';\n    moreUrl = moreUrl.replace(/%QUERY%/, vars.qEncoded);\n    const moreLabel = this.box.fullResultsLabel.replace(/%QUERY%/, `<em>${qDisp}</em>`);\n    vars = _.extend({}, vars, {qDisplay: qDisp, boxId: this.identifier, label: this.box.label});\n    return _.extend({}, vars, {\n      buttons: this.states.makeButtons(\n        {new: this.box.templates.newSearchButton, more: this.box.templates.moreResultsButton},\n        {new: newUrl, more: moreUrl},\n        {new: this.box.newSearchLabel, more: moreLabel},\n        this.box.state\n      ),\n      stateMessage: this.box.state.stateMessage(vars, this.box),\n      infoMessage: this.box.state.infoMessage(vars, this.box),\n    });\n  },\n\n  getSubViewHook: function(vars, subView, container) {\n    let subViewContainer = $(this.box.templates.resultContainer(vars));\n    container.find(this.subViewContainerHook).append(subViewContainer);\n    return subViewContainer;\n  },\n\n  prepContainer: function(vars, container) {\n    container = ContainerView.prototype.prepContainer(vars, container, this);\n    ImagesLoaded(container).on('progress', () => {\n      Utils.layout.update();\n      Utils.layout.jumpToElement();\n    });\n    /* This should fix an annoying issue on mobile where touching a link that\n     * also has a BS tooltip causes the tooltip to persist when you go back.\n     * Now it should just hide the tooltip when you touch it. */\n    container.find('a[data-bs-toggle=\"tooltip\"]').on('click', (ev) => {\n      let $el = $(ev.currentTarget);\n      Bootstrap.Tooltip.getInstance($el[0]).hide();\n    });\n    return container;\n  },\n});\n\n\nconst Result = BaseView.extend({\n  /* View for one bento box result. The template to use is passed to\n   * the initialization method, and the data is pulled from the model\n   * and passed to the template (on \"vars\") during rendering. */\n  events: {\n    'click h4 a': 'clickedTitle',\n    'contextmenu h4 a': 'rightClickedTitle',\n    'click a.btn.externalLink': 'clickedGetItButton',\n    'contextmenu a.btn.externalLink': 'rightClickedGetItButton',\n    'click .reportBrokenLink': 'showBrokenLinkModal',\n    'click .modal button.close': 'hideBrokenLinkModal',\n  },\n\n  initialize: function(options) {\n    this.label = options.label;\n    this.identifier = options.identifier;\n    this.template = _.template(options.template);\n    this.modal = null;\n  },\n\n  prepVars: function(vars) {\n    vars = _.extend(this.model.attributes);\n    if (vars.summary && vars.summary.length >= Config.maxSummaryLength) {\n      vars.summary = Utils.truncateText(vars.summary, Config.summaryTruncatePoint);\n    }\n    if (vars.title && vars.title.length >= Config.maxSummaryLength) {\n      vars.title = Utils.truncateText(vars.title, Config.titleTruncatePoint);\n    }\n    let linkId = encodeURIComponent(`untlbb-${vars.q}-${vars.title}-${this.identifier}`);\n    return _.extend({}, vars, {\n      resultId: this.identifier,\n      linkId: linkId,\n      itemVisited: sessionStorage.getItem(linkId) == 'visited',\n      typeInfo: Utils.getTypeInfo(vars),\n    });\n  },\n\n  showBrokenLinkModal: function(ev) {\n    ev.preventDefault();\n    let $el = $(ev.currentTarget);\n    let id = `#modal-${$el.attr('id')}`;\n    let href = $el.attr('href');\n    if (Config.isMobile()) {\n      window.open(href);\n    } else {\n      let $iframe = $(`${id} iframe`);\n      if (!$iframe.attr('src')) {\n        $iframe.attr('src', href);\n      }\n      this.modal = new Bootstrap.Modal($(id)[0], {keyboard: true});\n      this.modal.show();\n    }\n    EventChannel.trigger(\n      `broken-link-button-clicked:${this.identifier}`,\n      {'label': this.label}\n    );\n  },\n\n  hideBrokenLinkModal: function(ev) {\n    this.modal.hide();\n  },\n\n  externalLinkAction: function(ev, preventDefault, evChannelEventName) {\n    if (preventDefault) {\n      ev.preventDefault();\n    }\n    sessionStorage.setItem($(ev.currentTarget).attr('data-id'), 'visited');\n    this.$el.find('.btn.reportBrokenLink').removeClass('d-none');\n    Utils.layout.update();\n  },\n\n  clickedTitle: function(ev) {\n    this.externalLinkAction(ev, false, 'item-title-clicked');\n  },\n\n  clickedGetItButton: function(ev) {\n    this.externalLinkAction(ev, false, 'item-button-clicked');\n  },\n\n  rightClickedTitle: function(ev) {\n    this.externalLinkAction(ev, false, 'item-title-right-clicked');\n  },\n\n  rightClickedGetItButton: function(ev) {\n    this.externalLinkAction(ev, false, 'item-button-right-clicked');\n  }\n});\n\n\nexport {\n  selectBox,\n  Default,\n  BestBet,\n  ExactCourse,\n  BottomLinks,\n  BoxesContainer,\n  BentoBox,\n  Result,\n};\n","/* app/app.js\nBento Box App Main Module\n*/\n\nimport $ from 'jquery';\nimport Backbone from 'backbone';\nimport EventChannel from './events.js';\nimport * as Config from './config.js';\nimport * as Utils from './utils.js';\nimport * as SearchViews from './views/search-form.js';\nimport * as BentoViews from './views/bento-box.js';\n\n\nexport function doOnDomReady() {\n  Utils.layout.update();\n}\n\n\nfunction listenForGlobalEvents() {\n  /* Add listeners to global elements for global events. */\n\n  /* 1. Listen for URL hash changes to ensure proper behavior (due to\n   * nav links OR back/forward buttons being clicked). */\n  window.addEventListener('hashchange', function(ev) {\n    Utils.layout.jumpToElementId = Backbone.history.location.hash.slice(1);\n    BentoViews.selectBox(Utils.layout.jumpToElementId);\n    Utils.layout.jumpToElement();\n  });\n  \n  /* 2. Listen for individual boxes to report they've been rendered so\n   * that the overall layout can be updated. */\n  EventChannel.on('bento-box-rendered', (data) => {\n    Utils.layout.update();\n    Utils.layout.jumpToElement();\n    if (Utils.layout.jumpToElementId == data.boxId) {\n      BentoViews.selectBox(Utils.layout.jumpToElementId);\n    }\n  });\n}\n\n\n/*\nfunction tweakTitlesAndBreadCrumbs(urlParams) {\n  let title = 'Search It All';\n  if (urlParams.boxes.raw && !urlParams.getParsed('includeAll')) {\n    title = 'Search Selected Materials';\n  }\n  $('.content__title').html(title);\n  $('#content nav li.breadcrumb-item.this a').html(title);\n  document.title = title + ' - University Libraries - UNT';\n}\n*/\n\n\nconst viewController = {\n  /* One-off object that activates, deactivates, and renders groups of\n   * views in concert to provide holistic bento behavior. */\n  search: new SearchViews.Search({el: '#search'}),\n  nav: new SearchViews.Nav({el: '#bento-navbar'}),\n  default: new BentoViews.Default({el: '#default'}),\n  boxes: new BentoViews.BoxesContainer({el: '#bentoBoxes'}),\n  bestBet: new BentoViews.BestBet({el: '#bestBet'}),\n  exactCourse: new BentoViews.ExactCourse({el: '#exactCourse'}),\n  bottomLinks: new BentoViews.BottomLinks({el: '#bottomLinks'}),\n\n  navBoxes: function() {\n    return this.boxes.boxLayouts.nav;\n  },\n\n  activate: function(views, vars) {\n    views.forEach((view) => view.activate(vars));\n  },\n\n  deactivate: function(views) {\n    views.forEach((view) => view.deactivate());\n  },\n\n  activateOnSearchSuccess: function(views, vars) {\n    views.forEach((view) => {\n      let successEvent = `bento-box-collection-success:${view.collection.type}`;\n      view.listenToOnce(EventChannel, successEvent, (vars) => {\n        if (view.isNeeded(vars)) {\n          view.activate(vars);\n        }\n      });\n    });\n  },\n\n  render: function() {\n    const q = Config.urlParams.q\n    let vars = {\n      q: q.raw,\n      qEncoded: q.encoded,\n      qDisplay: Utils.prepQueryForDisplay(q.raw),\n      bottomLinks: {},\n      navItems: []\n    };\n    this.deactivate([\n      this.default, this.boxes, this.bestBet, this.exactCourse, this.bottomLinks\n    ]);\n    return vars.q === null ? this.renderDefault(vars) : this.renderSearch(vars);\n  },\n\n  renderDefault: function(vars) {\n    vars.navItems = Config.boxes.initDefaultNavItems(this.navBoxes());\n    this.activate([this.search, this.nav, this.default], vars);\n    return vars;\n  },\n\n  renderSearch: function(vars) {\n    vars.navItems = Config.boxes.initResultNavItems(this.navBoxes());\n    vars.navItems.push({url: '#other-searches', label: 'Other Searches'});\n    this.activateOnSearchSuccess([this.bestBet, this.exactCourse]);\n    this.activate([this.search, this.nav, this.boxes, this.bottomLinks], vars);\n    return vars;\n  },\n};\n\n\nexport function startBentoBox() {\n  listenForGlobalEvents();\n\n  const AppRouter = Backbone.Router.extend({\n    routes: {'': 'main'},\n    views: viewController,\n\n    main: function(qs) {\n      /* This method fires when a page is first loaded and every time a\n       * new search is submitted. */\n      Utils.layout.jumpToElementId = Backbone.history.location.hash.slice(1);\n      Config.urlParams.initialize();\n      this.views.boxes.initBoxes(\n        Config.urlParams.getParsed('boxes'),\n        Config.urlParams.getParsed('includeAll')\n      );\n      let vars = this.views.render();\n      if (vars.q !== null) {\n        EventChannel.trigger('search', vars);\n      }\n    },\n  });\n\n  let appRouter = new AppRouter();\n  appRouter.listenTo(EventChannel, 'searchform:search', function(params) {\n    appRouter.navigate(Config.urlParams.getQS({q: params.q}), {trigger: true});\n  });\n\n  Backbone.history.start({\n    pushState: true,\n    root: window.location.pathname,\n    hashChange: false,\n    trailingSlash: true,\n  });\n};\n","/*\n * fontawesome.js -- Contains initialization for fontawesome API\n */\n\nimport {\n  register,\n  InjectCSS,\n  ReplaceElements,\n  MutationObserver,\n} from '@fortawesome/fontawesome-svg-core/plugins';\n\nimport {\n  // Imports for Main Library Template\n  faBars,\n  faBuildingColumns,\n  faCaretDown,\n  faCaretRight,\n  faCommentsQuestion,\n  faDiagramNested,\n  faDollarSign,\n  faEllipsis,\n  faEnvelope,\n  faLocationDot,\n  faMagnifyingGlass,\n  faMessageDots,\n  faPaperPlane,\n  faPaste,\n  faPhone,\n  faPhoneSquare,\n  faRss,\n  faSignsPost,\n  faUniversalAccess,\n  faUserClock,\n  faUsers,\n  faXmark,\n\n  // Bento Box CONTENT Icons\n  faArchive,\n  faBook,\n  faCloudMusic,\n  faCode,\n  faCompactDisc,\n  faCube,\n  faDatabase,\n  faFile,\n  faFilm,\n  faGameBoard,\n  faGamepad,\n  faImages,\n  faLink,\n  faListMusic,\n  faNewspaper,\n  faTabletAndroidAlt,\n  faVideo,\n\n  // Other Bento Box Icons\n  faArrowUpRightFromSquare,\n  faArrowUpToArc,\n  faCheck,\n  faExclamationTriangle,\n  faGraduationCap,\n  faNotesMedical,\n  faScrewdriverWrench,\n  faSearch,\n  faTimes,\n  faThumbsUp,\n} from '@awesome.me/kit-261a22fc18/icons/classic/solid';\n\nimport {\n  faCircleNotch,\n} from '@awesome.me/kit-261a22fc18/icons/sharp-duotone/solid';\n\nimport {\n  // Imports for Main Library Template\n  faCalendarClock,\n  faCircleExclamation,\n  faClock,\n  faDiagramNested as faDiagramNestedD,\n  faMagnifyingGlass as faMagnifyingGlassD,\n  faMagnifyingGlassPlus,\n  faUniversity,\n  faUserLock,\n  faUsers as faUsersD,\n} from '@awesome.me/kit-261a22fc18/icons/duotone/solid';\n\nimport {\n  // Imports for Main Library Template\n  faFacebookF,\n  faGithubAlt,\n  faInstagram,\n  faXTwitter,\n  faYoutube,\n} from '@awesome.me/kit-261a22fc18/icons/classic/brands';\n\nimport {\n  // Imports for Main Library Template\n  faUntEagle,\n  faPthMark,\n  faOkMark,\n} from '@awesome.me/kit-261a22fc18/icons/kit/custom';\n\n\nconst api = register([InjectCSS, ReplaceElements, MutationObserver]);\napi.config.showMissingIcons = true;\n\napi.library.add(\n  faArchive,\n  faArrowUpRightFromSquare,\n  faArrowUpToArc,\n  faBars,\n  faBook,\n  faBuildingColumns,\n  faCalendarClock,\n  faCaretDown,\n  faCaretRight,\n  faCheck,\n  faCircleExclamation,\n  faCircleNotch,\n  faClock,\n  faCloudMusic,\n  faCode,\n  faCommentsQuestion,\n  faCompactDisc,\n  faCube,\n  faDatabase,\n  faDiagramNested,\n  faDiagramNestedD,\n  faDollarSign,\n  faEllipsis,\n  faEnvelope,\n  faExclamationTriangle,\n  faFacebookF,\n  faFile,\n  faFilm,\n  faGameBoard,\n  faGamepad,\n  faGithubAlt,\n  faGraduationCap,\n  faImages,\n  faInstagram,\n  faLink,\n  faListMusic,\n  faLocationDot,\n  faMagnifyingGlass,\n  faMagnifyingGlassD,\n  faMagnifyingGlassPlus,\n  faMessageDots,\n  faNewspaper,\n  faNotesMedical,\n  faOkMark,\n  faPaperPlane,\n  faPaste,\n  faPhone,\n  faPhoneSquare,\n  faPthMark,\n  faRss,\n  faScrewdriverWrench,\n  faSearch,\n  faSignsPost,\n  faTabletAndroidAlt,\n  faThumbsUp,\n  faTimes,\n  faVideo,\n  faUniversalAccess,\n  faUniversity,\n  faUntEagle,\n  faUserClock,\n  faUserLock,\n  faUsers,\n  faUsersD,\n  faXmark,\n  faXTwitter,\n  faYoutube,\n)\n\nexport { api };\n","/* unt-init.js\n * Contains code for initializing UNT library template components\n */\n\nimport 'FromWWW/assets/omni/scripts/display.alerts.js';\nimport { OffCanvasSearch } from 'FromWWW/assets/omni/scripts/search.offcanvas.js';\nimport { DropdownManager } from 'FromWWW/assets/omni/scripts/display.dropdowns.js';\nimport { LibraryHours } from 'FromWWW/assets/omni/scripts/display.hours.js';\nimport { AnchorUtility } from 'FromWWW/assets/omni/scripts/display.anchors.js';\nimport { IdentifierHelper } from 'FromWWW/assets/omni/scripts/search.identifiers.js';\nimport { ChatManager } from 'FromWWW/assets/omni/scripts/display.chat.js';\nimport { SearchDropdown } from 'FromWWW/assets/omni/scripts/search-dropdowns.js';\nimport dropdownsJson from 'FromWWW/assets/omni/data/dropdowns.json';\nimport utilsYaml from 'FromWWW/_data/utils.yaml';\nimport YAML from 'yaml';\n\n\nexport function initializeScripts() {\n  const utilsData = YAML.parse(utilsYaml);\n  window.untLib = {\n    respectDnt: ['1', 'yes'].includes(navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack),\n    searchDropdowns: utilsData.search_dropdowns\n  };\n  const offCanvasSearchUtil = new OffCanvasSearch();\n  const dropdownManager = new DropdownManager({\n    dataSrc: dropdownsJson,\n  });\n  const libraryHours = new LibraryHours(dropdownManager);\n  const anchorUtility = new AnchorUtility();\n  const identifierHelper = new IdentifierHelper();\n  new SearchDropdown(\n    'bento-offcanvas-other-search-options',\n    'bento-offcanvas-q',\n    window.untLib.searchDropdowns[\"default_bento\"]\n  );\n  const chatManager = new ChatManager();\n}\n\nexport { onDomReady, optInTooltips } from 'FromWWW/assets/omni/scripts/utils.js';\n","/* main.js\nBento Box App Initialization\n*/\n\nimport $ from 'jquery';\nimport * as Unt from './unt-init.js';\nimport * as App from './app/app.js';\nimport { api } from './fontawesome.js';\n\n\nUnt.initializeScripts();\nUnt.onDomReady(() => {\n  Unt.optInTooltips();\n  api.dom.i2svg();\n  api.dom.watch();\n  $('body').show();\n  App.doOnDomReady();\n});\nApp.startBentoBox();\n"],"names":["SearchDropdown","layout","selector","jumpToElementId","update","this","length","masonry","percentPosition","horizontalOrder","transitionDuration","jumpToElement","elementId","document","getElementById","scrollIntoView","getTypeInfo","vars","label","format","undefined","type","defaultCls","externalLink","words","replace","toLowerCase","split","_findClasses","mapping","_search","result","slice","faClasses","prepQueryForDisplay","q","truncate","decodeURI","join","truncateText","text","truncatePoint","i","charAt","match","substring","BentoBoxResult","extend","BentoBox","model","totalCount","newSearchUrl","fullResultsUrl","url","initialize","models","options","searchEnabled","maxResults","otherFields","push","parse","response","field","value","results","returnResults","r","pstring","Object","entries","article_title","title","article_authors","authorList","publication","issn","citation","journal_title","journalTitle","date","volume","issue","pages","startPage","numPages","content_type","link","results_url","map","key","encodeURIComponent","brokenFormBaseUrl","disableSearch","doSearch","fetch","data","success","trigger","error","getWindowCols","window","innerWidth","windowCols","addEventListener","event","new_cols","urlParams","validKeys","_getEncoded","val","boxes","_getParsed","includeAll","_getQSParam","rawSP","URLSearchParams","location","search","raw","get","encoded","getEncoded","parsed","getParsed","what","getQSParam","getQS","overrides","newQPs","param","newQS","boxStates","disabled","infoMessage","box","stateMessage","templates","disabledMessage","errorMessage","loading","loadingMessage","noResults","noResultsMessage","needsButtons","new","more","getResultState","collection","getStartingState","makeButtons","urls","labels","state","buttons","header","main","bType","bLoc","includeText","boxDefaults","fullResultsLabel","newSearchLabel","defaultNewSearchUrl","boxContainer","newSearchButton","moreResultsButton","resultContainer","articles","code","guides","defaultFullResultsUrl","databases","courses","referenceWorks","journals","digitalLibrary","booksAndMore","librarian","initResultNavItems","whichBoxes","initDefaultNavItems","boxesDisplay","defaults","nav","col1","col2","col3","do","reqBoxNames","reqBoxes","displayBoxes","allBoxes","concat","item","reqBox","BaseView","renderEventLabel","reset","view","activate","render","$el","show","deactivate","hide","isNeeded","triggerRenderEvent","prepVars","prepContainer","container","template","empty","append","ContainerView","subViews","forEach","subView","clearSubViews","remove","initSubViews","getSubViewHook","setElement","Search","selectors","events","listenTo","renderDidYouMean","submitSearch","ev","preventDefault","getFormVars","find","searchInput","articlesColl","didYouMean","qDisplay","term","didYouMeanTerm","html","removeClass","Nav","selectBox","selectedId","sbClasses","addClass","Default","BestBet","Boolean","bestBet","ExactCourse","exactMatches","exactMatch","courseUrl","course","sections","sec","instructor","BottomLinks","identifier","bottomLinks","query","qEncoded","boxId","BoxesContainer","subViewHook","boxPicker","columnClasses","boxLayouts","currentLayout","reOrderBoxes","initBoxes","boxNames","setBoxLayout","columnClass","default","subContainer","subViewContainerHook","states","prototype","Result","trunc","qDisp","newUrl","moreUrl","moreLabel","subViewContainer","on","currentTarget","getInstance","modal","attributes","summary","linkId","resultId","itemVisited","sessionStorage","getItem","typeInfo","showBrokenLinkModal","id","attr","href","userAgent","navigator","vendor","opera","test","substr","open","$iframe","keyboard","hideBrokenLinkModal","externalLinkAction","evChannelEventName","setItem","clickedTitle","clickedGetItButton","rightClickedTitle","rightClickedGetItButton","viewController","el","exactCourse","navBoxes","views","activateOnSearchSuccess","successEvent","listenToOnce","navItems","renderDefault","renderSearch","api","config","showMissingIcons","library","add","utilsData","untLib","respectDnt","includes","doNotTrack","msDoNotTrack","searchDropdowns","search_dropdowns","OffCanvasSearch","dropdownManager","DropdownManager","dataSrc","LibraryHours","AnchorUtility","IdentifierHelper","ChatManager","dom","i2svg","watch","hash","appRouter","routes","qs","params","navigate","start","pushState","root","pathname","hashChange","trailingSlash"],"sourceRoot":""}