@internetarchive/collection-browser 4.5.2 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (520) hide show
  1. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.editorconfig +29 -0
  2. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.github/workflows/ci.yml +27 -0
  3. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.github/workflows/gh-pages-main.yml +39 -0
  4. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.github/workflows/npm-publish.yml +39 -0
  5. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.github/workflows/pr-preview.yml +38 -0
  6. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.husky/pre-commit +1 -0
  7. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/.prettierignore +1 -0
  8. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/LICENSE +661 -0
  9. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/README.md +84 -0
  10. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/eslint.config.mjs +53 -0
  11. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/index.html +24 -0
  12. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/index.ts +29 -0
  13. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/local.archive.org.cert +86 -0
  14. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/local.archive.org.key +27 -0
  15. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/package.json +120 -0
  16. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/renovate.json +6 -0
  17. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/app-root.ts +1284 -0
  18. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/arrow-left.ts +10 -0
  19. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/arrow-right.ts +10 -0
  20. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/chevron.ts +4 -0
  21. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/close-circle-dark.ts +5 -0
  22. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/contract.ts +9 -0
  23. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/empty-query.ts +5 -0
  24. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/expand.ts +9 -0
  25. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/eye-closed.ts +5 -0
  26. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/eye.ts +5 -0
  27. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/favorite-filled.ts +10 -0
  28. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/favorite-unfilled.ts +9 -0
  29. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/filter.ts +10 -0
  30. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/login-required.ts +18 -0
  31. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/account.ts +14 -0
  32. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/audio.ts +14 -0
  33. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/collection.ts +12 -0
  34. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/data.ts +15 -0
  35. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/etree.ts +14 -0
  36. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/film.ts +14 -0
  37. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/images.ts +13 -0
  38. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/radio.ts +15 -0
  39. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/search.ts +14 -0
  40. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/software.ts +13 -0
  41. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/texts.ts +13 -0
  42. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/tv-commercial.ts +12 -0
  43. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/tv-fact-check.ts +12 -0
  44. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/tv-quote.ts +12 -0
  45. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/tv.ts +14 -0
  46. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/video.ts +14 -0
  47. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/mediatype/web.ts +13 -0
  48. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/null-result.ts +5 -0
  49. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/quote.ts +7 -0
  50. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/restricted.ts +13 -0
  51. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/reviews.ts +11 -0
  52. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/upload.ts +12 -0
  53. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/assets/img/icons/views.ts +11 -0
  54. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/circular-activity-indicator.ts +64 -0
  55. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-browser.ts +3165 -0
  56. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/facet-row.ts +309 -0
  57. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/facet-tombstone-row.ts +40 -0
  58. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/facets-template.ts +85 -0
  59. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/models.ts +10 -0
  60. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/more-facets-content.ts +644 -0
  61. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/more-facets-pagination.ts +294 -0
  62. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/dedupe.ts +44 -0
  63. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/browser-language/browser-language-heuristic.ts +27 -0
  64. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/index.ts +3 -0
  65. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-heuristic.ts +17 -0
  66. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-map.ts +70 -0
  67. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-entity-map.ts +79 -0
  68. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts +93 -0
  69. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/models.ts +36 -0
  70. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/smart-facet-bar.ts +437 -0
  71. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/smart-facet-button.ts +145 -0
  72. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/smart-facet-dropdown.ts +185 -0
  73. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/smart-facet-equals.ts +16 -0
  74. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/smart-facets/smart-facet-heuristics.ts +26 -0
  75. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets/toggle-switch.ts +174 -0
  76. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/collection-facets.ts +1013 -0
  77. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/data-source/collection-browser-data-source-interface.ts +351 -0
  78. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/data-source/collection-browser-data-source.ts +1474 -0
  79. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/data-source/collection-browser-query-state.ts +60 -0
  80. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/data-source/models.ts +56 -0
  81. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/empty-placeholder.ts +192 -0
  82. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/expanded-date-picker.ts +191 -0
  83. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/language-code-handler/language-code-handler.ts +64 -0
  84. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/language-code-handler/language-code-mapping.ts +564 -0
  85. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/manage/manage-bar.ts +276 -0
  86. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/manage/remove-items-modal-content.ts +102 -0
  87. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/mediatype/mediatype-config.ts +146 -0
  88. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/models.ts +895 -0
  89. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/restoration-state-handler.ts +550 -0
  90. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/alpha-bar-tooltip.ts +53 -0
  91. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/alpha-bar.ts +252 -0
  92. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/compact.ts +5 -0
  93. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/list.ts +5 -0
  94. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/sort-toggle-disabled.ts +15 -0
  95. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/sort-toggle-down.ts +17 -0
  96. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/sort-toggle-up.ts +17 -0
  97. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/sort-triangle.ts +5 -0
  98. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/img/tile.ts +5 -0
  99. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/sort-filter-bar/sort-filter-bar.ts +733 -0
  100. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/styles/ia-button.ts +139 -0
  101. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/styles/item-image-styles.ts +124 -0
  102. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/styles/sr-only.ts +18 -0
  103. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/styles/tile-action-styles.ts +59 -0
  104. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/base-tile-component.ts +124 -0
  105. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/collection-browser-loading-tile.ts +26 -0
  106. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/account-tile.ts +113 -0
  107. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/collection-tile.ts +184 -0
  108. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/item-tile.ts +347 -0
  109. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/search-tile.ts +90 -0
  110. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/styles/tile-grid-shared-styles.ts +130 -0
  111. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/grid/tile-stats.ts +211 -0
  112. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/hover/hover-pane-controller.ts +638 -0
  113. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/hover/tile-hover-pane.ts +184 -0
  114. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/image-block.ts +162 -0
  115. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/item-image.ts +214 -0
  116. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/list/tile-list-compact-header.ts +112 -0
  117. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/list/tile-list-compact.ts +278 -0
  118. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/list/tile-list.ts +718 -0
  119. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/models.ts +21 -0
  120. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/overlay/icon-overlay.ts +57 -0
  121. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/overlay/text-overlay.ts +79 -0
  122. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/review-block.ts +130 -0
  123. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/text-snippet-block.ts +132 -0
  124. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/tile-dispatcher.ts +637 -0
  125. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/tile-display-value-provider.ts +133 -0
  126. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/tiles/tile-mediatype-icon.ts +133 -0
  127. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/analytics-events.ts +29 -0
  128. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/array-equals.ts +8 -0
  129. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/collapse-repeated-quotes.ts +13 -0
  130. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/date-filter-field.ts +11 -0
  131. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/facet-utils.ts +183 -0
  132. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/format-count.ts +95 -0
  133. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/format-date.ts +62 -0
  134. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/format-unit-size.ts +43 -0
  135. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/local-date-from-utc.ts +15 -0
  136. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/log.ts +14 -0
  137. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/resolve-mediatype.ts +26 -0
  138. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/src/utils/sha1.ts +9 -0
  139. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-browser.test.ts +2639 -0
  140. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets/facet-row.test.ts +421 -0
  141. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets/facets-template.test.ts +139 -0
  142. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets/more-facets-content.test.ts +231 -0
  143. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets/more-facets-pagination.test.ts +201 -0
  144. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets/toggle-switch.test.ts +164 -0
  145. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/collection-facets.test.ts +928 -0
  146. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/data-source/collection-browser-data-source.test.ts +193 -0
  147. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/empty-placeholder.test.ts +88 -0
  148. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/expanded-date-picker.test.ts +201 -0
  149. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/icon-overlay.test.ts +38 -0
  150. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/image-block.test.ts +247 -0
  151. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/item-image.test.ts +220 -0
  152. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/manage/manage-bar.test.ts +347 -0
  153. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/manage/remove-items-modal-content.test.ts +81 -0
  154. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/mediatype-config.test.ts +11 -0
  155. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/mocks/mock-analytics-handler.ts +30 -0
  156. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/mocks/mock-search-responses.ts +1364 -0
  157. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/mocks/mock-search-service.ts +134 -0
  158. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/restoration-state-handler.test.ts +480 -0
  159. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/review-block.test.ts +62 -0
  160. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/sort-filter-bar/alpha-bar-tooltip.test.ts +17 -0
  161. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/sort-filter-bar/alpha-bar.test.ts +101 -0
  162. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/sort-filter-bar/sort-filter-bar.test.ts +443 -0
  163. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/text-overlay.test.ts +55 -0
  164. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/text-snippet-block.test.ts +85 -0
  165. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tile-stats.test.ts +191 -0
  166. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/grid/account-tile.test.ts +121 -0
  167. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/grid/collection-tile.test.ts +114 -0
  168. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/grid/item-tile.test.ts +520 -0
  169. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/grid/search-tile.test.ts +75 -0
  170. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/hover/hover-pane-controller.test.ts +482 -0
  171. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/hover/tile-hover-pane.test.ts +80 -0
  172. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/list/tile-list-compact-header.test.ts +43 -0
  173. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/list/tile-list-compact.test.ts +282 -0
  174. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/list/tile-list.test.ts +576 -0
  175. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/tile-dispatcher.test.ts +320 -0
  176. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/tile-display-value-provider.test.ts +172 -0
  177. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/tiles/tile-mediatype-icon.test.ts +160 -0
  178. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/utils/array-equals.test.ts +31 -0
  179. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/utils/format-count.test.ts +32 -0
  180. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/utils/format-date.test.ts +89 -0
  181. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/utils/format-unit-size.test.ts +21 -0
  182. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/test/utils/local-date-from-utc.test.ts +37 -0
  183. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/tsconfig.json +25 -0
  184. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/types/dompurify.d.ts +1 -0
  185. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/vite.config.ts +29 -0
  186. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/web-dev-server.config.mjs +30 -0
  187. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/web-test-runner.config.mjs +52 -0
  188. package/.claude/worktrees/WEBDEV-8677-bump-field-parsers/yarn.lock +5965 -0
  189. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.editorconfig +29 -0
  190. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.github/workflows/ci.yml +29 -0
  191. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.github/workflows/gh-pages-main.yml +41 -0
  192. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.github/workflows/npm-publish.yml +42 -0
  193. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.github/workflows/pr-preview.yml +40 -0
  194. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.husky/pre-commit +1 -0
  195. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/.prettierignore +1 -0
  196. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/LICENSE +661 -0
  197. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/README.md +68 -0
  198. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/eslint.config.mjs +53 -0
  199. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/index.html +24 -0
  200. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/index.ts +29 -0
  201. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/local.archive.org.cert +86 -0
  202. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/local.archive.org.key +27 -0
  203. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/package.json +129 -0
  204. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/pnpm-lock.yaml +7366 -0
  205. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/pnpm-workspace.yaml +46 -0
  206. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/renovate.json +6 -0
  207. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/app-root.ts +1284 -0
  208. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/arrow-left.ts +10 -0
  209. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/arrow-right.ts +10 -0
  210. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/chevron.ts +4 -0
  211. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/close-circle-dark.ts +5 -0
  212. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/contract.ts +9 -0
  213. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/empty-query.ts +5 -0
  214. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/expand.ts +9 -0
  215. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/eye-closed.ts +5 -0
  216. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/eye.ts +5 -0
  217. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/favorite-filled.ts +10 -0
  218. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/favorite-unfilled.ts +9 -0
  219. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/filter.ts +10 -0
  220. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/login-required.ts +18 -0
  221. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/account.ts +14 -0
  222. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/audio.ts +14 -0
  223. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/collection.ts +12 -0
  224. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/data.ts +15 -0
  225. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/etree.ts +14 -0
  226. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/film.ts +14 -0
  227. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/images.ts +13 -0
  228. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/radio.ts +15 -0
  229. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/search.ts +14 -0
  230. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/software.ts +13 -0
  231. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/texts.ts +13 -0
  232. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/tv-commercial.ts +12 -0
  233. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/tv-fact-check.ts +12 -0
  234. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/tv-quote.ts +12 -0
  235. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/tv.ts +14 -0
  236. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/video.ts +14 -0
  237. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/mediatype/web.ts +13 -0
  238. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/null-result.ts +5 -0
  239. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/quote.ts +7 -0
  240. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/restricted.ts +13 -0
  241. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/reviews.ts +11 -0
  242. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/upload.ts +12 -0
  243. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/assets/img/icons/views.ts +11 -0
  244. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/circular-activity-indicator.ts +64 -0
  245. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-browser.ts +3165 -0
  246. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/facet-row.ts +309 -0
  247. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/facet-tombstone-row.ts +40 -0
  248. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/facets-template.ts +85 -0
  249. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/models.ts +10 -0
  250. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/more-facets-content.ts +644 -0
  251. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/more-facets-pagination.ts +294 -0
  252. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/dedupe.ts +44 -0
  253. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/browser-language/browser-language-heuristic.ts +27 -0
  254. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/index.ts +3 -0
  255. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-heuristic.ts +17 -0
  256. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-map.ts +70 -0
  257. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-entity-map.ts +79 -0
  258. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts +93 -0
  259. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/models.ts +36 -0
  260. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/smart-facet-bar.ts +437 -0
  261. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/smart-facet-button.ts +145 -0
  262. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/smart-facet-dropdown.ts +185 -0
  263. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/smart-facet-equals.ts +16 -0
  264. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/smart-facets/smart-facet-heuristics.ts +26 -0
  265. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets/toggle-switch.ts +174 -0
  266. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/collection-facets.ts +1013 -0
  267. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/data-source/collection-browser-data-source-interface.ts +351 -0
  268. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/data-source/collection-browser-data-source.ts +1474 -0
  269. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/data-source/collection-browser-query-state.ts +60 -0
  270. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/data-source/models.ts +56 -0
  271. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/empty-placeholder.ts +192 -0
  272. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/expanded-date-picker.ts +191 -0
  273. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/language-code-handler/language-code-handler.ts +64 -0
  274. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/language-code-handler/language-code-mapping.ts +564 -0
  275. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/manage/manage-bar.ts +276 -0
  276. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/manage/remove-items-modal-content.ts +102 -0
  277. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/mediatype/mediatype-config.ts +146 -0
  278. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/models.ts +895 -0
  279. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/restoration-state-handler.ts +550 -0
  280. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/alpha-bar-tooltip.ts +53 -0
  281. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/alpha-bar.ts +252 -0
  282. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/compact.ts +5 -0
  283. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/list.ts +5 -0
  284. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/sort-toggle-disabled.ts +15 -0
  285. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/sort-toggle-down.ts +17 -0
  286. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/sort-toggle-up.ts +17 -0
  287. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/sort-triangle.ts +5 -0
  288. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/img/tile.ts +5 -0
  289. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/sort-filter-bar/sort-filter-bar.ts +733 -0
  290. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/styles/ia-button.ts +139 -0
  291. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/styles/item-image-styles.ts +124 -0
  292. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/styles/sr-only.ts +18 -0
  293. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/styles/tile-action-styles.ts +59 -0
  294. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/base-tile-component.ts +124 -0
  295. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/collection-browser-loading-tile.ts +26 -0
  296. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/account-tile.ts +113 -0
  297. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/collection-tile.ts +184 -0
  298. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/item-tile.ts +347 -0
  299. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/search-tile.ts +90 -0
  300. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/styles/tile-grid-shared-styles.ts +130 -0
  301. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/grid/tile-stats.ts +211 -0
  302. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/hover/hover-pane-controller.ts +638 -0
  303. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/hover/tile-hover-pane.ts +184 -0
  304. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/image-block.ts +162 -0
  305. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/item-image.ts +214 -0
  306. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/list/tile-list-compact-header.ts +112 -0
  307. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/list/tile-list-compact.ts +278 -0
  308. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/list/tile-list.ts +718 -0
  309. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/models.ts +21 -0
  310. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/overlay/icon-overlay.ts +57 -0
  311. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/overlay/text-overlay.ts +79 -0
  312. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/review-block.ts +130 -0
  313. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/text-snippet-block.ts +132 -0
  314. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/tile-dispatcher.ts +637 -0
  315. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/tile-display-value-provider.ts +133 -0
  316. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/tiles/tile-mediatype-icon.ts +133 -0
  317. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/analytics-events.ts +29 -0
  318. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/array-equals.ts +8 -0
  319. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/collapse-repeated-quotes.ts +13 -0
  320. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/date-filter-field.ts +11 -0
  321. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/facet-utils.ts +183 -0
  322. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/format-count.ts +95 -0
  323. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/format-date.ts +62 -0
  324. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/format-unit-size.ts +43 -0
  325. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/local-date-from-utc.ts +15 -0
  326. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/log.ts +14 -0
  327. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/resolve-mediatype.ts +26 -0
  328. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/src/utils/sha1.ts +9 -0
  329. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-browser.test.ts +2639 -0
  330. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets/facet-row.test.ts +421 -0
  331. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets/facets-template.test.ts +139 -0
  332. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets/more-facets-content.test.ts +231 -0
  333. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets/more-facets-pagination.test.ts +201 -0
  334. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets/toggle-switch.test.ts +164 -0
  335. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/collection-facets.test.ts +928 -0
  336. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/data-source/collection-browser-data-source.test.ts +193 -0
  337. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/empty-placeholder.test.ts +88 -0
  338. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/expanded-date-picker.test.ts +201 -0
  339. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/icon-overlay.test.ts +38 -0
  340. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/image-block.test.ts +247 -0
  341. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/item-image.test.ts +220 -0
  342. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/manage/manage-bar.test.ts +347 -0
  343. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/manage/remove-items-modal-content.test.ts +81 -0
  344. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/mediatype-config.test.ts +11 -0
  345. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/mocks/mock-analytics-handler.ts +30 -0
  346. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/mocks/mock-search-responses.ts +1364 -0
  347. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/mocks/mock-search-service.ts +134 -0
  348. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/restoration-state-handler.test.ts +480 -0
  349. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/review-block.test.ts +62 -0
  350. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/sort-filter-bar/alpha-bar-tooltip.test.ts +17 -0
  351. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/sort-filter-bar/alpha-bar.test.ts +101 -0
  352. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/sort-filter-bar/sort-filter-bar.test.ts +443 -0
  353. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/text-overlay.test.ts +55 -0
  354. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/text-snippet-block.test.ts +85 -0
  355. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tile-stats.test.ts +191 -0
  356. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/grid/account-tile.test.ts +121 -0
  357. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/grid/collection-tile.test.ts +114 -0
  358. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/grid/item-tile.test.ts +520 -0
  359. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/grid/search-tile.test.ts +75 -0
  360. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/hover/hover-pane-controller.test.ts +482 -0
  361. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/hover/tile-hover-pane.test.ts +80 -0
  362. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/list/tile-list-compact-header.test.ts +43 -0
  363. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/list/tile-list-compact.test.ts +282 -0
  364. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/list/tile-list.test.ts +576 -0
  365. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/tile-dispatcher.test.ts +320 -0
  366. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/tile-display-value-provider.test.ts +172 -0
  367. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/tiles/tile-mediatype-icon.test.ts +160 -0
  368. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/utils/array-equals.test.ts +31 -0
  369. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/utils/format-count.test.ts +32 -0
  370. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/utils/format-date.test.ts +89 -0
  371. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/utils/format-unit-size.test.ts +21 -0
  372. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/test/utils/local-date-from-utc.test.ts +37 -0
  373. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/tsconfig.json +25 -0
  374. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/types/dompurify.d.ts +1 -0
  375. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/vite.config.ts +29 -0
  376. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/web-dev-server.config.mjs +30 -0
  377. package/.claude/worktrees/WEBDEV-9119-migrate-to-pnpm/web-test-runner.config.mjs +52 -0
  378. package/.editorconfig +29 -29
  379. package/.github/workflows/ci.yml +27 -27
  380. package/.github/workflows/gh-pages-main.yml +39 -39
  381. package/.github/workflows/npm-publish.yml +39 -39
  382. package/.github/workflows/pr-preview.yml +38 -38
  383. package/.husky/pre-commit +1 -1
  384. package/.prettierignore +1 -1
  385. package/LICENSE +661 -661
  386. package/README.md +83 -83
  387. package/dist/index.js.map +1 -1
  388. package/dist/src/app-root.d.ts +1 -1
  389. package/dist/src/app-root.js +683 -683
  390. package/dist/src/app-root.js.map +1 -1
  391. package/dist/src/assets/img/icons/arrow-left.d.ts +1 -1
  392. package/dist/src/assets/img/icons/arrow-right.d.ts +1 -1
  393. package/dist/src/assets/img/icons/chevron.d.ts +1 -1
  394. package/dist/src/assets/img/icons/close-circle-dark.d.ts +1 -1
  395. package/dist/src/assets/img/icons/contract.d.ts +1 -1
  396. package/dist/src/assets/img/icons/empty-query.d.ts +1 -1
  397. package/dist/src/assets/img/icons/expand.d.ts +1 -1
  398. package/dist/src/assets/img/icons/eye-closed.d.ts +1 -1
  399. package/dist/src/assets/img/icons/eye.d.ts +1 -1
  400. package/dist/src/assets/img/icons/favorite-filled.d.ts +1 -1
  401. package/dist/src/assets/img/icons/favorite-unfilled.d.ts +1 -1
  402. package/dist/src/assets/img/icons/filter.d.ts +1 -1
  403. package/dist/src/assets/img/icons/login-required.d.ts +1 -1
  404. package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -1
  405. package/dist/src/assets/img/icons/mediatype/audio.d.ts +1 -1
  406. package/dist/src/assets/img/icons/mediatype/collection.d.ts +1 -1
  407. package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -1
  408. package/dist/src/assets/img/icons/mediatype/etree.d.ts +1 -1
  409. package/dist/src/assets/img/icons/mediatype/film.d.ts +1 -1
  410. package/dist/src/assets/img/icons/mediatype/images.d.ts +1 -1
  411. package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -1
  412. package/dist/src/assets/img/icons/mediatype/search.d.ts +1 -1
  413. package/dist/src/assets/img/icons/mediatype/software.d.ts +1 -1
  414. package/dist/src/assets/img/icons/mediatype/texts.d.ts +1 -1
  415. package/dist/src/assets/img/icons/mediatype/tv-commercial.d.ts +1 -1
  416. package/dist/src/assets/img/icons/mediatype/tv-fact-check.d.ts +1 -1
  417. package/dist/src/assets/img/icons/mediatype/tv-quote.d.ts +1 -1
  418. package/dist/src/assets/img/icons/mediatype/tv.d.ts +1 -1
  419. package/dist/src/assets/img/icons/mediatype/video.d.ts +1 -1
  420. package/dist/src/assets/img/icons/mediatype/web.d.ts +1 -1
  421. package/dist/src/assets/img/icons/null-result.d.ts +1 -1
  422. package/dist/src/assets/img/icons/quote.d.ts +1 -1
  423. package/dist/src/assets/img/icons/restricted.d.ts +1 -1
  424. package/dist/src/assets/img/icons/reviews.d.ts +1 -1
  425. package/dist/src/assets/img/icons/upload.d.ts +1 -1
  426. package/dist/src/assets/img/icons/views.d.ts +1 -1
  427. package/dist/src/circular-activity-indicator.d.ts +1 -1
  428. package/dist/src/collection-browser.js +766 -766
  429. package/dist/src/collection-browser.js.map +1 -1
  430. package/dist/src/collection-facets/facet-row.js +143 -143
  431. package/dist/src/collection-facets/facet-row.js.map +1 -1
  432. package/dist/src/collection-facets/facet-tombstone-row.d.ts +1 -1
  433. package/dist/src/collection-facets/facets-template.js +24 -24
  434. package/dist/src/collection-facets/facets-template.js.map +1 -1
  435. package/dist/src/collection-facets/smart-facets/smart-facet-button.d.ts +1 -1
  436. package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.d.ts +1 -1
  437. package/dist/src/collection-facets/toggle-switch.d.ts +1 -1
  438. package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
  439. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  440. package/dist/src/restoration-state-handler.js.map +1 -1
  441. package/dist/src/sort-filter-bar/alpha-bar-tooltip.d.ts +1 -1
  442. package/dist/src/sort-filter-bar/img/compact.d.ts +1 -1
  443. package/dist/src/sort-filter-bar/img/list.d.ts +1 -1
  444. package/dist/src/sort-filter-bar/img/sort-toggle-disabled.d.ts +1 -1
  445. package/dist/src/sort-filter-bar/img/sort-toggle-down.d.ts +1 -1
  446. package/dist/src/sort-filter-bar/img/sort-toggle-up.d.ts +1 -1
  447. package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -1
  448. package/dist/src/sort-filter-bar/img/tile.d.ts +1 -1
  449. package/dist/src/styles/tile-action-styles.js +43 -43
  450. package/dist/src/styles/tile-action-styles.js.map +1 -1
  451. package/dist/src/tiles/base-tile-component.js +11 -11
  452. package/dist/src/tiles/base-tile-component.js.map +1 -1
  453. package/dist/src/tiles/collection-browser-loading-tile.d.ts +1 -1
  454. package/dist/src/tiles/grid/item-tile.js +138 -138
  455. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  456. package/dist/src/tiles/hover/hover-pane-controller.js +40 -32
  457. package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
  458. package/dist/src/tiles/image-block.d.ts +1 -1
  459. package/dist/src/tiles/item-image.d.ts +1 -1
  460. package/dist/src/tiles/list/tile-list-compact-header.d.ts +1 -1
  461. package/dist/src/tiles/list/tile-list-compact-header.js +62 -62
  462. package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
  463. package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
  464. package/dist/src/tiles/list/tile-list-compact.js +123 -123
  465. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  466. package/dist/src/tiles/list/tile-list.js +310 -310
  467. package/dist/src/tiles/list/tile-list.js.map +1 -1
  468. package/dist/src/tiles/models.js.map +1 -1
  469. package/dist/src/tiles/tile-dispatcher.d.ts +1 -1
  470. package/dist/src/tiles/tile-dispatcher.js +286 -286
  471. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  472. package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
  473. package/dist/src/tiles/tile-mediatype-icon.d.ts +1 -1
  474. package/dist/src/utils/date-filter-field.js.map +1 -1
  475. package/dist/test/collection-browser.test.js +203 -203
  476. package/dist/test/collection-browser.test.js.map +1 -1
  477. package/dist/test/collection-facets/facet-row.test.js +31 -31
  478. package/dist/test/collection-facets/facet-row.test.js.map +1 -1
  479. package/dist/test/tiles/grid/item-tile.test.js +77 -77
  480. package/dist/test/tiles/grid/item-tile.test.js.map +1 -1
  481. package/dist/test/tiles/hover/hover-pane-controller.test.js +57 -50
  482. package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -1
  483. package/dist/test/tiles/list/tile-list.test.js +134 -134
  484. package/dist/test/tiles/list/tile-list.test.js.map +1 -1
  485. package/dist/test/tiles/tile-dispatcher.test.js +92 -92
  486. package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
  487. package/eslint.config.mjs +53 -53
  488. package/index.html +24 -24
  489. package/index.ts +29 -29
  490. package/local.archive.org.cert +86 -86
  491. package/local.archive.org.key +27 -27
  492. package/package.json +120 -120
  493. package/renovate.json +6 -6
  494. package/src/app-root.ts +1284 -1284
  495. package/src/collection-browser.ts +3165 -3165
  496. package/src/collection-facets/facet-row.ts +309 -309
  497. package/src/collection-facets/facets-template.ts +85 -85
  498. package/src/data-source/collection-browser-data-source-interface.ts +351 -351
  499. package/src/data-source/collection-browser-data-source.ts +1474 -1474
  500. package/src/restoration-state-handler.ts +550 -550
  501. package/src/styles/tile-action-styles.ts +59 -59
  502. package/src/tiles/base-tile-component.ts +124 -124
  503. package/src/tiles/grid/item-tile.ts +347 -347
  504. package/src/tiles/hover/hover-pane-controller.ts +638 -630
  505. package/src/tiles/list/tile-list-compact-header.ts +112 -112
  506. package/src/tiles/list/tile-list-compact.ts +278 -278
  507. package/src/tiles/list/tile-list.ts +718 -718
  508. package/src/tiles/models.ts +21 -21
  509. package/src/tiles/tile-dispatcher.ts +637 -637
  510. package/src/tiles/tile-display-value-provider.ts +133 -133
  511. package/src/utils/date-filter-field.ts +11 -11
  512. package/test/collection-browser.test.ts +2639 -2639
  513. package/test/collection-facets/facet-row.test.ts +421 -421
  514. package/test/tiles/grid/item-tile.test.ts +520 -520
  515. package/test/tiles/hover/hover-pane-controller.test.ts +482 -454
  516. package/test/tiles/list/tile-list.test.ts +576 -576
  517. package/test/tiles/tile-dispatcher.test.ts +320 -320
  518. package/tsconfig.json +25 -25
  519. package/web-dev-server.config.mjs +30 -30
  520. package/web-test-runner.config.mjs +52 -52
@@ -0,0 +1,1013 @@
1
+ import {
2
+ css,
3
+ html,
4
+ LitElement,
5
+ PropertyValues,
6
+ nothing,
7
+ TemplateResult,
8
+ } from 'lit';
9
+ import { customElement, property, state } from 'lit/decorators.js';
10
+ import { map } from 'lit/directives/map.js';
11
+ import { ref } from 'lit/directives/ref.js';
12
+ import { msg } from '@lit/localize';
13
+ import { classMap } from 'lit/directives/class-map.js';
14
+ import {
15
+ Aggregation,
16
+ AggregationSortType,
17
+ Bucket,
18
+ FilterMap,
19
+ SearchServiceInterface,
20
+ SearchType,
21
+ } from '@internetarchive/search-service';
22
+ import '@internetarchive/histogram-date-range';
23
+ import '@internetarchive/feature-feedback';
24
+ import {
25
+ ModalConfig,
26
+ ModalManagerInterface,
27
+ } from '@internetarchive/modal-manager';
28
+ import type { FeatureFeedbackServiceInterface } from '@internetarchive/feature-feedback';
29
+ import type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manager';
30
+ import type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';
31
+ import type { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer';
32
+ import type {
33
+ BarScalingOption,
34
+ BinSnappingInterval,
35
+ } from '@internetarchive/histogram-date-range';
36
+ import chevronIcon from './assets/img/icons/chevron';
37
+ import expandIcon from './assets/img/icons/expand';
38
+ import {
39
+ FacetOption,
40
+ SelectedFacets,
41
+ FacetGroup,
42
+ FacetBucket,
43
+ defaultFacetDisplayOrder,
44
+ facetTitles,
45
+ customFacetDisplayNames,
46
+ lendingFacetKeysVisibility,
47
+ LendingFacetKey,
48
+ suppressedCollections,
49
+ defaultFacetSort,
50
+ FacetEventDetails,
51
+ } from './models';
52
+ import type {
53
+ CollectionTitles,
54
+ PageSpecifierParams,
55
+ TVChannelAliases,
56
+ } from './data-source/models';
57
+ import {
58
+ analyticsActions,
59
+ analyticsCategories,
60
+ } from './utils/analytics-events';
61
+ import { srOnlyStyle } from './styles/sr-only';
62
+ import { ExpandedDatePicker } from './expanded-date-picker';
63
+ import {
64
+ sortBucketsBySelectionState,
65
+ updateSelectedFacetBucket,
66
+ } from './utils/facet-utils';
67
+
68
+ import '@internetarchive/histogram-date-range';
69
+ import './collection-facets/more-facets-content';
70
+ import './collection-facets/facets-template';
71
+ import './collection-facets/facet-tombstone-row';
72
+ import './expanded-date-picker';
73
+
74
+ @customElement('collection-facets')
75
+ export class CollectionFacets extends LitElement {
76
+ @property({ type: Object }) searchService?: SearchServiceInterface;
77
+
78
+ @property({ type: Number }) searchType?: SearchType;
79
+
80
+ @property({ type: Object }) aggregations?: Record<string, Aggregation>;
81
+
82
+ @property({ type: Object }) histogramAggregation?: Aggregation;
83
+
84
+ @property({ type: String }) minSelectedDate?: string;
85
+
86
+ @property({ type: String }) maxSelectedDate?: string;
87
+
88
+ @property({ type: Boolean }) moreLinksVisible = true;
89
+
90
+ @property({ type: Boolean }) facetsLoading = false;
91
+
92
+ @property({ type: Boolean }) histogramAggregationLoading = false;
93
+
94
+ @property({ type: Object }) selectedFacets?: SelectedFacets;
95
+
96
+ @property({ type: Boolean }) collapsableFacets = false;
97
+
98
+ @property({ type: Number }) contentWidth?: number;
99
+
100
+ @property({ type: Boolean }) showHistogramDatePicker = false;
101
+
102
+ @property({ type: Boolean }) allowExpandingDatePicker = false;
103
+
104
+ @property({ type: Boolean }) suppressMediatypeFacets = false;
105
+
106
+ @property({ type: String }) query?: string;
107
+
108
+ @property({ type: Array }) identifiers?: string[];
109
+
110
+ @property({ type: Object }) pageSpecifierParams?: PageSpecifierParams;
111
+
112
+ @property({ type: Array }) parentCollections: string[] = [];
113
+
114
+ @property({ type: Object }) filterMap?: FilterMap;
115
+
116
+ @property({ type: String }) baseNavigationUrl?: string;
117
+
118
+ @property({ type: String }) collectionPagePath: string = '/details/';
119
+
120
+ @property({ type: Boolean }) isManageView = false;
121
+
122
+ @property({ type: Boolean }) isTvSearch = false;
123
+
124
+ @property({ type: Array }) facetDisplayOrder: FacetOption[] =
125
+ defaultFacetDisplayOrder;
126
+
127
+ @property({ type: Object, attribute: false })
128
+ modalManager?: ModalManagerInterface;
129
+
130
+ @property({ type: Object, attribute: false })
131
+ resizeObserver?: SharedResizeObserverInterface;
132
+
133
+ @property({ type: Object, attribute: false })
134
+ featureFeedbackService?: FeatureFeedbackServiceInterface;
135
+
136
+ @property({ type: Object, attribute: false })
137
+ recaptchaManager?: RecaptchaManagerInterface;
138
+
139
+ @property({ type: Object, attribute: false })
140
+ analyticsHandler?: AnalyticsManagerInterface;
141
+
142
+ @property({ type: Object, attribute: false })
143
+ collectionTitles?: CollectionTitles;
144
+
145
+ @property({ type: Object, attribute: false })
146
+ tvChannelAliases?: TVChannelAliases;
147
+
148
+ @state() openFacets: Record<FacetOption, boolean> = {
149
+ subject: false,
150
+ lending: false,
151
+ mediatype: false,
152
+ language: false,
153
+ creator: false,
154
+ collection: false,
155
+ year: false,
156
+ clip_type: false,
157
+ program: false,
158
+ person: false,
159
+ sponsor: false,
160
+ };
161
+
162
+ /**
163
+ * Maximum # of facet buckets to render per facet group
164
+ */
165
+ private allowedFacetCount = 6;
166
+
167
+ render() {
168
+ const containerClasses = classMap({
169
+ loading: this.facetsLoading,
170
+ managing: this.isManageView,
171
+ });
172
+
173
+ const heading = this.isTvSearch
174
+ ? msg('Date Published')
175
+ : msg('Year Published');
176
+
177
+ // Added data-testid for Playwright testing
178
+ // Using facet-group class and aria-labels is not ideal for Playwright locator
179
+ const datePickerLabelId = 'date-picker-label';
180
+ return html`
181
+ <div id="container" class=${containerClasses}>
182
+ ${this.showHistogramDatePicker &&
183
+ (this.histogramAggregation || this.histogramAggregationLoading)
184
+ ? html`
185
+ <section
186
+ class="facet-group"
187
+ aria-labelledby=${datePickerLabelId}
188
+ data-testid="facet-group-header-label-date-picker"
189
+ >
190
+ <h3 id=${datePickerLabelId}>
191
+ ${heading} <span class="sr-only">${msg('range filter')}</span>
192
+ ${this.expandDatePickerBtnTemplate}
193
+ </h3>
194
+ ${this.histogramTemplate}
195
+ </section>
196
+ `
197
+ : nothing}
198
+ ${this.collectionPartOfTemplate}
199
+ <slot name="facets-top"></slot>
200
+ ${this.mergedFacets.map(facetGroup =>
201
+ this.getFacetGroupTemplate(facetGroup),
202
+ )}
203
+ </div>
204
+ `;
205
+ }
206
+
207
+ private get collectionPartOfTemplate(): TemplateResult | typeof nothing {
208
+ // We only display the "Part Of" section on collection pages
209
+ if (!this.parentCollections?.length) return nothing;
210
+
211
+ // Added data-testid for Playwright testing
212
+ // Using className and aria-labels is not ideal for Playwright locator
213
+ const headingId = 'partof-heading';
214
+ return html`
215
+ <section
216
+ class="facet-group partof-collections"
217
+ aria-labelledby=${headingId}
218
+ data-testid="facet-group-partof-collections"
219
+ >
220
+ <div class="facet-group-header">
221
+ <h3 id=${headingId}>${msg('Part Of')}</h3>
222
+ </div>
223
+ <ul>
224
+ ${map(this.parentCollections, collxn => {
225
+ const collectionURL = `${this.baseNavigationUrl}${this.collectionPagePath}${collxn}`;
226
+
227
+ return html` <li>
228
+ <a
229
+ href=${collectionURL}
230
+ data-id=${collxn}
231
+ @click=${this.partOfCollectionClicked}
232
+ >
233
+ ${this.collectionTitles?.get(collxn) ?? collxn}
234
+ </a>
235
+ </li>`;
236
+ })}
237
+ </ul>
238
+ </section>
239
+ `;
240
+ }
241
+
242
+ private partOfCollectionClicked(e: Event): void {
243
+ this.analyticsHandler?.sendEvent({
244
+ category: analyticsCategories.default,
245
+ action: analyticsActions.partOfCollectionClicked,
246
+ label: (e.target as HTMLElement).dataset.id,
247
+ });
248
+ }
249
+
250
+ /**
251
+ * Properties to pass into the date-picker histogram component
252
+ */
253
+ private get histogramProps() {
254
+ const { histogramAggregation: aggregation } = this;
255
+ if (!aggregation) return undefined;
256
+
257
+ // Normalize some properties from the raw aggregation
258
+ const firstYear =
259
+ aggregation.first_bucket_year ?? aggregation.first_bucket_key;
260
+ const lastYear =
261
+ aggregation.last_bucket_year ?? aggregation.last_bucket_key;
262
+ if (firstYear == null || lastYear == null) return undefined; // We at least need a start/end year defined
263
+
264
+ const firstMonth = aggregation.first_bucket_month ?? 1;
265
+ const lastMonth = aggregation.last_bucket_month ?? 12;
266
+
267
+ const yearInterval = aggregation.interval ?? 1;
268
+ const monthInterval = aggregation.interval_in_months ?? 12;
269
+
270
+ const zeroPadMonth = (month: number) => month.toString().padStart(2, '0');
271
+
272
+ // The date picker is configured differently for TV search, allowing month-level resolution
273
+ if (this.isTvSearch) {
274
+ // Whether the bucket interval is less than a year
275
+ // (i.e., requires individual months to be handled & labeled)
276
+ const mustHandleMonths = monthInterval < 12;
277
+
278
+ return {
279
+ buckets: aggregation.buckets as number[],
280
+ dateFormat: 'YYYY-MM',
281
+ tooltipDateFormat: mustHandleMonths ? 'MMM YYYY' : 'YYYY',
282
+ tooltipLabel: 'broadcast',
283
+ binSnapping: (mustHandleMonths
284
+ ? 'month'
285
+ : 'year') as BinSnappingInterval,
286
+ barScaling: 'linear' as BarScalingOption,
287
+ minDate: `${firstYear}-${zeroPadMonth(firstMonth)}`,
288
+ maxDate: `${lastYear}-${zeroPadMonth(lastMonth + monthInterval - 1)}`,
289
+ };
290
+ }
291
+
292
+ // All other search types use the same configuration
293
+ return {
294
+ buckets: aggregation.buckets as number[],
295
+ dateFormat: 'YYYY',
296
+ tooltipDateFormat: 'YYYY',
297
+ tooltipLabel: 'item',
298
+ binSnapping: 'year' as BinSnappingInterval,
299
+ barScaling: 'logarithmic' as BarScalingOption,
300
+ minDate: `${firstYear}`,
301
+ maxDate: `${lastYear + yearInterval - 1}`,
302
+ };
303
+ }
304
+
305
+ /**
306
+ * Opens a modal dialog containing an enlarged version of the date picker.
307
+ */
308
+ private showDatePickerModal(): void {
309
+ const { histogramProps } = this;
310
+ if (!histogramProps) return;
311
+
312
+ const {
313
+ buckets,
314
+ dateFormat,
315
+ tooltipDateFormat,
316
+ tooltipLabel,
317
+ binSnapping,
318
+ barScaling,
319
+ minDate,
320
+ maxDate,
321
+ } = histogramProps;
322
+
323
+ // Because the modal manager does not clear its DOM content after being closed,
324
+ // it may try to render the exact same date picker template when it is reopened.
325
+ // And because it isn't actually a descendent of this collection-facets component,
326
+ // changes to the template defined here may not trigger a reactive update to the date
327
+ // picker, resulting in it displaying a stale date range.
328
+ // This ref callback ensures that every time the date picker modal is opened, it will
329
+ // always propagate the most recent date range into the date picker regardless of
330
+ // whether Lit thinks the update is necessary.
331
+ const expandedDatePickerChanged = (elmt?: Element) => {
332
+ if (elmt && elmt instanceof ExpandedDatePicker) {
333
+ const expandedDatePicker = elmt as ExpandedDatePicker;
334
+ expandedDatePicker.minSelectedDate = this.minSelectedDate;
335
+ expandedDatePicker.maxSelectedDate = this.maxSelectedDate;
336
+ }
337
+ };
338
+
339
+ const customModalContent = html`
340
+ <expanded-date-picker
341
+ ${ref(expandedDatePickerChanged)}
342
+ .minDate=${minDate}
343
+ .maxDate=${maxDate}
344
+ .minSelectedDate=${this.minSelectedDate}
345
+ .maxSelectedDate=${this.maxSelectedDate}
346
+ .customDateFormat=${dateFormat}
347
+ .customTooltipDateFormat=${tooltipDateFormat}
348
+ .customTooltipLabel=${tooltipLabel}
349
+ .binSnapping=${binSnapping}
350
+ .barScaling=${barScaling}
351
+ .buckets=${buckets}
352
+ .modalManager=${this.modalManager}
353
+ .analyticsHandler=${this.analyticsHandler}
354
+ @histogramDateRangeApplied=${this.histogramDateRangeUpdated}
355
+ @modalClosed=${this.handleExpandedDatePickerClosed}
356
+ ></expanded-date-picker>
357
+ `;
358
+
359
+ const config = new ModalConfig({
360
+ bodyColor: '#fff',
361
+ headerColor: '#194880',
362
+ showHeaderLogo: false,
363
+ closeOnBackdropClick: true, // TODO: want to fire analytics
364
+ title: html`${msg('Select a date range')}`,
365
+ });
366
+
367
+ this.modalManager?.classList.add('expanded-date-picker');
368
+ this.modalManager?.showModal({
369
+ config,
370
+ customModalContent,
371
+ userClosedModalCallback: this.handleExpandedDatePickerClosed,
372
+ });
373
+
374
+ this.analyticsHandler?.sendEvent({
375
+ category: analyticsCategories.default,
376
+ action: analyticsActions.histogramExpanded,
377
+ label: window.location.href,
378
+ });
379
+ }
380
+
381
+ private handleExpandedDatePickerClosed = (): void => {
382
+ this.modalManager?.classList.remove('expanded-date-picker');
383
+ };
384
+
385
+ updated(changed: PropertyValues) {
386
+ if (changed.has('selectedFacets')) {
387
+ this.dispatchFacetsChangedEvent();
388
+ }
389
+ }
390
+
391
+ // TODO: want to fire analytics?
392
+ private dispatchFacetsChangedEvent() {
393
+ const event = new CustomEvent<SelectedFacets>('facetsChanged', {
394
+ detail: this.selectedFacets,
395
+ });
396
+ this.dispatchEvent(event);
397
+ }
398
+
399
+ /**
400
+ * Template for the "Expand" button to show the date picker modal, or
401
+ * `nothing` if that button should currently not be shown.
402
+ */
403
+ private get expandDatePickerBtnTemplate(): TemplateResult | typeof nothing {
404
+ return this.allowExpandingDatePicker && !this.facetsLoading
405
+ ? html`<button
406
+ class="expand-date-picker-btn"
407
+ aria-haspopup="dialog"
408
+ @click=${this.showDatePickerModal}
409
+ >
410
+ <span class="sr-only">${msg('Expand date histogram')}</span>
411
+ <span aria-hidden="true">${expandIcon}</span>
412
+ </button>`
413
+ : nothing;
414
+ }
415
+
416
+ private get histogramTemplate(): TemplateResult | typeof nothing {
417
+ if (this.histogramAggregationLoading) {
418
+ return html` <div class="histogram-loading-indicator">&hellip;</div> `;
419
+ }
420
+
421
+ const { histogramProps } = this;
422
+ if (!histogramProps) return nothing;
423
+
424
+ const {
425
+ buckets,
426
+ dateFormat,
427
+ tooltipDateFormat,
428
+ tooltipLabel,
429
+ binSnapping,
430
+ barScaling,
431
+ minDate,
432
+ maxDate,
433
+ } = histogramProps;
434
+
435
+ return html`
436
+ <histogram-date-range
437
+ class=${this.isTvSearch ? 'wide-inputs' : ''}
438
+ .minDate=${minDate}
439
+ .maxDate=${maxDate}
440
+ .minSelectedDate=${this.minSelectedDate ?? minDate}
441
+ .maxSelectedDate=${this.maxSelectedDate ?? maxDate}
442
+ .updateDelay=${100}
443
+ .dateFormat=${dateFormat}
444
+ .tooltipDateFormat=${tooltipDateFormat}
445
+ .tooltipLabel=${tooltipLabel}
446
+ .binSnapping=${binSnapping}
447
+ .barScaling=${barScaling}
448
+ .bins=${buckets}
449
+ missingDataMessage="..."
450
+ .width=${this.collapsableFacets && this.contentWidth
451
+ ? this.contentWidth
452
+ : 180}
453
+ @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
454
+ ></histogram-date-range>
455
+ `;
456
+ }
457
+
458
+ /**
459
+ * Dispatches a `histogramDateRangeUpdated` event with the date range copied from the
460
+ * input event.
461
+ *
462
+ * Arrow function to ensure `this` is always bound to the current component.
463
+ */
464
+ private histogramDateRangeUpdated = (
465
+ e: CustomEvent<{
466
+ minDate: string;
467
+ maxDate: string;
468
+ }>,
469
+ ): void => {
470
+ const { minDate, maxDate } = e.detail;
471
+ const event = new CustomEvent('histogramDateRangeUpdated', {
472
+ detail: { minDate, maxDate },
473
+ });
474
+ this.dispatchEvent(event);
475
+ };
476
+
477
+ /**
478
+ * Combines the selected facets with the aggregations to create a single list of facets
479
+ */
480
+ private get mergedFacets(): FacetGroup[] {
481
+ const facetGroups: FacetGroup[] = [];
482
+
483
+ this.facetDisplayOrder.forEach(facetKey => {
484
+ if (facetKey === 'mediatype' && this.suppressMediatypeFacets) return;
485
+
486
+ const selectedFacetGroup = this.selectedFacetGroups.find(
487
+ group => group.key === facetKey,
488
+ );
489
+ const aggregateFacetGroup = this.aggregationFacetGroups.find(
490
+ group => group.key === facetKey,
491
+ );
492
+
493
+ // if the user selected a facet, but it's not in the aggregation, we add it as-is
494
+ if (selectedFacetGroup && !aggregateFacetGroup) {
495
+ facetGroups.push(selectedFacetGroup);
496
+ return;
497
+ }
498
+
499
+ // if we don't have an aggregate facet group, don't add this to the list
500
+ if (!aggregateFacetGroup) return;
501
+
502
+ // start with either the selected group if we have one, or the aggregate group
503
+ const facetGroup = selectedFacetGroup ?? aggregateFacetGroup;
504
+
505
+ // attach the counts to the selected buckets
506
+ let bucketsWithCount =
507
+ selectedFacetGroup?.buckets.map(bucket => {
508
+ const selectedBucket = aggregateFacetGroup.buckets.find(
509
+ b => b.key === bucket.key,
510
+ );
511
+ return selectedBucket
512
+ ? {
513
+ ...bucket,
514
+ count: selectedBucket.count,
515
+ }
516
+ : bucket;
517
+ }) ?? [];
518
+
519
+ // append any additional buckets that were not selected
520
+ aggregateFacetGroup.buckets.forEach(bucket => {
521
+ const existingBucket = bucketsWithCount.find(b => b.key === bucket.key);
522
+ if (existingBucket) return;
523
+ bucketsWithCount.push(bucket);
524
+ });
525
+
526
+ /**
527
+ * render limited facet items on page facet area
528
+ *
529
+ * - by-default we are showing 6 items
530
+ * - additionally want to show all items (selected/suppressed) in page facet area
531
+ */
532
+ let allowedFacetCount = Object.keys(
533
+ (selectedFacetGroup?.buckets as []) || [],
534
+ )?.length;
535
+ if (allowedFacetCount < this.allowedFacetCount) {
536
+ allowedFacetCount = this.allowedFacetCount; // splice start index from 0th
537
+ }
538
+
539
+ // For lending facets, only include a specific subset of buckets
540
+ if (facetKey === 'lending') {
541
+ bucketsWithCount = bucketsWithCount.filter(
542
+ bucket => lendingFacetKeysVisibility[bucket.key as LendingFacetKey],
543
+ );
544
+ }
545
+
546
+ // Sort the FacetBuckets so that selected and hidden buckets come before the rest
547
+ sortBucketsBySelectionState(bucketsWithCount, defaultFacetSort[facetKey]);
548
+
549
+ // For mediatype facets, ensure the collection bucket is always shown if present
550
+ if (facetKey === 'mediatype') {
551
+ const collectionIndex = bucketsWithCount.findIndex(
552
+ bucket => bucket.key === 'collection',
553
+ );
554
+
555
+ if (collectionIndex >= allowedFacetCount) {
556
+ const [collectionBucket] = bucketsWithCount.splice(
557
+ collectionIndex,
558
+ 1,
559
+ );
560
+
561
+ // If we're showing lots of selected facets, ensure we're not cutting off the last one
562
+ if (allowedFacetCount > this.allowedFacetCount) {
563
+ allowedFacetCount += 1;
564
+ }
565
+
566
+ bucketsWithCount.splice(allowedFacetCount - 1, 0, collectionBucket);
567
+ }
568
+ }
569
+
570
+ // For TV creator facets, uppercase the display text
571
+ if (facetKey === 'creator' && this.isTvSearch) {
572
+ bucketsWithCount.forEach(b => {
573
+ b.displayText = (b.displayText ?? b.key)?.toLocaleUpperCase();
574
+
575
+ const channelLabel = this.tvChannelAliases?.get(b.displayText);
576
+ if (channelLabel && channelLabel !== b.displayText) {
577
+ b.extraNote = `(${channelLabel})`;
578
+ }
579
+ });
580
+ }
581
+ // For TV clip_type facets, capitalize the display text
582
+ if (facetKey === 'clip_type') {
583
+ bucketsWithCount.forEach(b => {
584
+ b.displayText ??= b.key;
585
+ b.displayText =
586
+ b.displayText.charAt(0).toLocaleUpperCase() +
587
+ b.displayText.slice(1);
588
+ });
589
+ }
590
+
591
+ // slice off how many items we want to show in page facet area
592
+ facetGroup.buckets = bucketsWithCount.slice(0, allowedFacetCount);
593
+
594
+ facetGroups.push(facetGroup);
595
+ });
596
+
597
+ return facetGroups;
598
+ }
599
+
600
+ /**
601
+ * Converts the selected facets to a `FacetGroup` array,
602
+ * which is easier to work with
603
+ */
604
+ private get selectedFacetGroups(): FacetGroup[] {
605
+ if (!this.selectedFacets) return [];
606
+
607
+ const facetGroups: FacetGroup[] = Object.entries(this.selectedFacets).map(
608
+ ([key, selectedFacets]) => {
609
+ const option = key as FacetOption;
610
+ const title = facetTitles[option];
611
+
612
+ const buckets: FacetBucket[] = Object.entries(selectedFacets).map(
613
+ ([value, facetData]) => {
614
+ let displayText: string = value;
615
+ // For certain facet types/keys, we use a custom readable display name
616
+ const currentGroupCustomNames = customFacetDisplayNames[
617
+ option
618
+ ] as Record<string, string>;
619
+ if (currentGroupCustomNames) {
620
+ displayText = currentGroupCustomNames[value] ?? value;
621
+ }
622
+ return {
623
+ displayText,
624
+ key: value,
625
+ count: facetData.count,
626
+ state: facetData.state,
627
+ };
628
+ },
629
+ );
630
+
631
+ return {
632
+ title,
633
+ key: option,
634
+ buckets,
635
+ };
636
+ },
637
+ );
638
+
639
+ return facetGroups;
640
+ }
641
+
642
+ /**
643
+ * Converts the raw `aggregations` to `FacetGroups`, which are easier to use
644
+ */
645
+ private get aggregationFacetGroups(): FacetGroup[] {
646
+ const facetGroups: FacetGroup[] = [];
647
+ Object.entries(this.aggregations ?? []).forEach(([key, aggregation]) => {
648
+ // the year_histogram and date_histogram data is in a different format so can't be handled here
649
+ if (['year_histogram', 'date_histogram'].includes(key)) return;
650
+
651
+ const option = key as FacetOption;
652
+ const title = facetTitles[option];
653
+ if (!title) return;
654
+
655
+ let castedBuckets = aggregation.getSortedBuckets(
656
+ defaultFacetSort[option],
657
+ ) as Bucket[];
658
+
659
+ if (option === 'collection') {
660
+ // we are not showing fav- collections or certain deemphasized collections in facets
661
+ castedBuckets = castedBuckets?.filter(bucket => {
662
+ const bucketKey = bucket?.key?.toString();
663
+ return (
664
+ !suppressedCollections[bucketKey] && !bucketKey?.startsWith('fav-')
665
+ );
666
+ });
667
+ }
668
+
669
+ const facetBuckets: FacetBucket[] = castedBuckets.map(bucket => {
670
+ const bucketKey = bucket.key;
671
+ let displayText = `${bucket.key}`;
672
+ // For certain facet types/keys, we use a custom readable display name
673
+ const currentGroupCustomNames = customFacetDisplayNames[
674
+ option
675
+ ] as Record<string, string>;
676
+ if (currentGroupCustomNames) {
677
+ displayText = currentGroupCustomNames[bucket.key] ?? `${bucket.key}`;
678
+ }
679
+ return {
680
+ displayText,
681
+ key: `${bucketKey}`,
682
+ count: bucket.doc_count,
683
+ state: 'none',
684
+ };
685
+ });
686
+ const group: FacetGroup = {
687
+ title,
688
+ key: option,
689
+ buckets: facetBuckets,
690
+ };
691
+ facetGroups.push(group);
692
+ });
693
+ return facetGroups;
694
+ }
695
+
696
+ /**
697
+ * Generate the template for a facet group with a header and the collapsible
698
+ * chevron for the mobile view
699
+ */
700
+ private getFacetGroupTemplate(
701
+ facetGroup: FacetGroup,
702
+ ): TemplateResult | typeof nothing {
703
+ if (!this.facetsLoading && facetGroup.buckets.length === 0) return nothing;
704
+
705
+ const { key } = facetGroup;
706
+ const isOpen = this.openFacets[key];
707
+ const collapser = html`
708
+ <span class="collapser ${isOpen ? 'open' : ''}"> ${chevronIcon} </span>
709
+ `;
710
+
711
+ const toggleCollapsed = () => {
712
+ const newOpenFacets = { ...this.openFacets };
713
+ newOpenFacets[key] = !isOpen;
714
+ this.openFacets = newOpenFacets;
715
+ };
716
+
717
+ // Added data-testid for Playwright testing
718
+ // Using className and aria-labels is not ideal for Playwright locator
719
+ const headerId = `facet-group-header-label-${facetGroup.key}`;
720
+ return html`
721
+ <section
722
+ class="facet-group ${this.collapsableFacets ? 'mobile' : ''}"
723
+ aria-labelledby=${headerId}
724
+ data-testid=${headerId}
725
+ >
726
+ <div class="facet-group-header">
727
+ <h3
728
+ id=${headerId}
729
+ @click=${toggleCollapsed}
730
+ @keyup=${toggleCollapsed}
731
+ >
732
+ ${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}
733
+ <span class="sr-only">filters</span>
734
+ </h3>
735
+ </div>
736
+ <div
737
+ class="facet-group-content ${isOpen ? 'open' : ''}"
738
+ data-testid="facet-group-content-${facetGroup.key}"
739
+ >
740
+ ${this.facetsLoading
741
+ ? this.getTombstoneFacetGroupTemplate()
742
+ : html`
743
+ ${this.getFacetTemplate(facetGroup)}
744
+ ${this.searchMoreFacetsLink(facetGroup)}
745
+ `}
746
+ </div>
747
+ </section>
748
+ `;
749
+ }
750
+
751
+ private getTombstoneFacetGroupTemplate(): TemplateResult {
752
+ // Render five tombstone rows
753
+ return html`
754
+ ${map(
755
+ Array(5).fill(null),
756
+ () => html`<facet-tombstone-row></facet-tombstone-row>`,
757
+ )}
758
+ `;
759
+ }
760
+
761
+ /**
762
+ * Generate the More... link button just below the facets group
763
+ *
764
+ * TODO: want to fire analytics?
765
+ */
766
+ private searchMoreFacetsLink(
767
+ facetGroup: FacetGroup,
768
+ ): TemplateResult | typeof nothing {
769
+ // Don't render More... links for FTS searches
770
+ if (!this.moreLinksVisible) {
771
+ return nothing;
772
+ }
773
+
774
+ // Don't render More... links for lending facets
775
+ if (facetGroup.key === 'lending') {
776
+ return nothing;
777
+ }
778
+
779
+ // Don't render More... link if the number of facets < this.allowedFacetCount
780
+ if (Object.keys(facetGroup.buckets).length < this.allowedFacetCount) {
781
+ return nothing;
782
+ }
783
+
784
+ // We sort years in numeric order by default, rather than bucket count
785
+ const facetSort = defaultFacetSort[facetGroup.key];
786
+
787
+ // Added data-testid for Playwright testing
788
+ // Using the className is not ideal for Playwright locator
789
+ return html`<button
790
+ class="more-link"
791
+ @click=${() => {
792
+ this.showMoreFacetsModal(facetGroup, facetSort);
793
+ this.analyticsHandler?.sendEvent({
794
+ category: analyticsCategories.default,
795
+ action: analyticsActions.showMoreFacetsModal,
796
+ label: facetGroup.key,
797
+ });
798
+ this.dispatchEvent(
799
+ new CustomEvent('showMoreFacets', { detail: facetGroup.key }),
800
+ );
801
+ }}
802
+ data-testid="more-link-btn"
803
+ >
804
+ More...
805
+ </button>`;
806
+ }
807
+
808
+ async showMoreFacetsModal(
809
+ facetGroup: FacetGroup,
810
+ sortedBy: AggregationSortType,
811
+ ): Promise<void> {
812
+ const customModalContent = html`
813
+ <more-facets-content
814
+ .analyticsHandler=${this.analyticsHandler}
815
+ .facetKey=${facetGroup.key}
816
+ .query=${this.query}
817
+ .identifiers=${this.identifiers}
818
+ .filterMap=${this.filterMap}
819
+ .pageSpecifierParams=${this.pageSpecifierParams}
820
+ .modalManager=${this.modalManager}
821
+ .searchService=${this.searchService}
822
+ .searchType=${this.searchType}
823
+ .collectionTitles=${this.collectionTitles}
824
+ .tvChannelAliases=${this.tvChannelAliases}
825
+ .selectedFacets=${this.selectedFacets}
826
+ .sortedBy=${sortedBy}
827
+ .isTvSearch=${this.isTvSearch}
828
+ @facetsChanged=${(e: CustomEvent) => {
829
+ const event = new CustomEvent<SelectedFacets>('facetsChanged', {
830
+ detail: e.detail,
831
+ bubbles: true,
832
+ composed: true,
833
+ });
834
+ this.dispatchEvent(event);
835
+ }}
836
+ >
837
+ </more-facets-content>
838
+ `;
839
+
840
+ const config = new ModalConfig({
841
+ bodyColor: '#fff',
842
+ headerColor: '#194880',
843
+ showHeaderLogo: false,
844
+ closeOnBackdropClick: true, // TODO: want to fire analytics
845
+ title: html`Select filters`,
846
+ });
847
+ this.modalManager?.classList.add('more-search-facets');
848
+ this.modalManager?.showModal({
849
+ config,
850
+ customModalContent,
851
+ userClosedModalCallback: () => {
852
+ this.modalManager?.classList.remove('more-search-facets');
853
+ },
854
+ });
855
+ }
856
+
857
+ /**
858
+ * Generate the list template for each bucket in a facet group
859
+ */
860
+ private getFacetTemplate(facetGroup: FacetGroup): TemplateResult {
861
+ return html`
862
+ <facets-template
863
+ .collectionPagePath=${this.collectionPagePath}
864
+ .facetGroup=${facetGroup}
865
+ .selectedFacets=${this.selectedFacets}
866
+ .collectionTitles=${this.collectionTitles}
867
+ @facetClick=${(e: CustomEvent<FacetEventDetails>) => {
868
+ this.selectedFacets = updateSelectedFacetBucket(
869
+ this.selectedFacets,
870
+ facetGroup.key,
871
+ e.detail.bucket,
872
+ true,
873
+ );
874
+
875
+ const event = new CustomEvent<SelectedFacets>('facetsChanged', {
876
+ detail: this.selectedFacets,
877
+ bubbles: true,
878
+ composed: true,
879
+ });
880
+ this.dispatchEvent(event);
881
+ }}
882
+ ></facets-template>
883
+ `;
884
+ }
885
+
886
+ static get styles() {
887
+ return [
888
+ srOnlyStyle,
889
+ css`
890
+ a:link {
891
+ text-decoration: none;
892
+ color: var(--ia-theme-link-color, #4b64ff);
893
+ }
894
+ a:link:hover {
895
+ text-decoration: underline;
896
+ }
897
+
898
+ #container.loading {
899
+ opacity: 0.5;
900
+ }
901
+
902
+ #container.managing {
903
+ opacity: 0.3;
904
+ }
905
+
906
+ .histogram-loading-indicator {
907
+ width: 100%;
908
+ height: 5.25rem;
909
+ margin-top: 1.75rem;
910
+ font-size: 1.4rem;
911
+ text-align: center;
912
+ }
913
+
914
+ .collapser {
915
+ display: inline-block;
916
+ cursor: pointer;
917
+ width: 10px;
918
+ height: 10px;
919
+ }
920
+
921
+ .collapser svg {
922
+ transition: transform 0.2s ease-in-out;
923
+ }
924
+
925
+ .collapser.open svg {
926
+ transform: rotate(90deg);
927
+ }
928
+
929
+ .facet-group {
930
+ margin-bottom: 2rem;
931
+ }
932
+
933
+ .facet-group h3 {
934
+ margin-bottom: 0.7rem;
935
+ }
936
+
937
+ .facet-group.mobile h3 {
938
+ cursor: pointer;
939
+ }
940
+
941
+ .facet-group-header {
942
+ display: flex;
943
+ margin-bottom: 0.7rem;
944
+ justify-content: space-between;
945
+ border-bottom: 1px solid rgb(232, 232, 232);
946
+ }
947
+
948
+ .facet-group-content {
949
+ transition: max-height 0.2s ease-in-out;
950
+ }
951
+
952
+ .facet-group.mobile .facet-group-content {
953
+ max-height: 0;
954
+ overflow: hidden;
955
+ }
956
+
957
+ .facet-group.mobile .facet-group-content.open {
958
+ max-height: 2000px;
959
+ }
960
+
961
+ .partof-collections ul {
962
+ list-style-type: none;
963
+ padding: 0;
964
+ font-size: 1.2rem;
965
+ }
966
+
967
+ h3 {
968
+ font-size: 1.4rem;
969
+ margin: 0;
970
+ }
971
+
972
+ .more-link {
973
+ font-size: 1.2rem;
974
+ text-decoration: none;
975
+ padding: 0;
976
+ margin-top: 0.25rem;
977
+ background: inherit;
978
+ border: 0;
979
+ color: var(--ia-theme-link-color, #4b64ff);
980
+ cursor: pointer;
981
+ }
982
+
983
+ #date-picker-label {
984
+ display: flex;
985
+ justify-content: space-between;
986
+ }
987
+
988
+ .expand-date-picker-btn {
989
+ margin: 0;
990
+ padding: 0;
991
+ border: 0;
992
+ appearance: none;
993
+ background: none;
994
+ cursor: pointer;
995
+ }
996
+
997
+ .expand-date-picker-btn svg {
998
+ width: 14px;
999
+ height: 14px;
1000
+ }
1001
+
1002
+ .sorting-icon {
1003
+ height: 15px;
1004
+ cursor: pointer;
1005
+ }
1006
+
1007
+ histogram-date-range.wide-inputs {
1008
+ --histogramDateRangeInputWidth: 4.8rem;
1009
+ }
1010
+ `,
1011
+ ];
1012
+ }
1013
+ }