ui_bibz 3.0.13 → 4.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (294) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -3
  3. data/.github/workflows/linter.yml +13 -12
  4. data/.overcommit.yml +6 -0
  5. data/.rubocop.yml +6 -0
  6. data/.ruby-version +1 -1
  7. data/Gemfile +19 -12
  8. data/Gemfile.lock +178 -138
  9. data/app/assets/config/ui_bibz.js +12 -0
  10. data/app/assets/javascripts/forms/formula.js +82 -0
  11. data/app/assets/javascripts/forms/input-connected.js +132 -0
  12. data/app/assets/javascripts/forms/jquery.multi-select-extend.js +52 -0
  13. data/app/assets/javascripts/forms.js +160 -0
  14. data/app/assets/javascripts/interfaces.js +56 -0
  15. data/app/assets/javascripts/tables.js +49 -0
  16. data/app/assets/javascripts/ui_bibz_js.js +37 -0
  17. data/app/assets/stylesheets/navigations/_nav.sass +2 -0
  18. data/app/assets/stylesheets/navigations/_navbar.sass +12 -0
  19. data/app/assets/stylesheets/navigations/_progress_bar.sass +2 -0
  20. data/app/assets/stylesheets/navigations/_toolbar.sass +3 -0
  21. data/app/assets/stylesheets/sass/_boxes.sass +1 -0
  22. data/app/assets/stylesheets/sass/_containers.sass +2 -0
  23. data/app/assets/stylesheets/sass/_fixes.sass +2 -0
  24. data/app/assets/stylesheets/sass/_forms.sass +8 -0
  25. data/app/assets/stylesheets/sass/_navigations.sass +4 -0
  26. data/app/assets/stylesheets/sass/_notifications.sass +4 -0
  27. data/app/assets/stylesheets/sass/_tables.sass +2 -0
  28. data/app/assets/stylesheets/sass/_variables_mixins_functions.sass +3 -0
  29. data/app/assets/stylesheets/sass/boxes/_card.sass +4 -0
  30. data/app/assets/stylesheets/sass/containers/_panel.scss +330 -0
  31. data/app/assets/stylesheets/sass/forms/_bootstrap_select.sass +5 -0
  32. data/app/assets/stylesheets/sass/forms/_button.sass +3 -0
  33. data/app/assets/stylesheets/sass/forms/_date_picker.sass +3 -0
  34. data/app/assets/stylesheets/sass/forms/_form_check.sass +10 -0
  35. data/app/assets/stylesheets/sass/forms/_formula_field.sass +17 -0
  36. data/app/assets/stylesheets/sass/forms/_multiselect.sass +44 -0
  37. data/app/assets/stylesheets/sass/forms/_range.sass +44 -0
  38. data/app/assets/stylesheets/sass/forms/_slider.sass +136 -0
  39. data/app/assets/stylesheets/sass/forms/_surround_field.sass +25 -0
  40. data/app/assets/stylesheets/sass/notifications/_badge.sass +5 -0
  41. data/app/assets/stylesheets/sass/notifications/_glyph.sass +3 -0
  42. data/app/assets/stylesheets/sass/notifications/_star.sass +2 -0
  43. data/app/assets/stylesheets/sass/notifications/_toast.sass +3 -0
  44. data/app/assets/stylesheets/sass/tables/_table.sass +39 -0
  45. data/app/assets/stylesheets/sass/tables/_table_card.sass +39 -0
  46. data/app/assets/stylesheets/ui_bibz.sass +26 -0
  47. data/bin/test +3 -5
  48. data/config/importmap.rb +19 -0
  49. data/config/initializers/assets.rb +5 -0
  50. data/config/initializers/will_paginate.rb +1 -3
  51. data/lib/ui_bibz/builders/data_html_options_builder.rb +118 -0
  52. data/lib/ui_bibz/builders/html_classes_builder.rb +89 -0
  53. data/lib/ui_bibz/builders/html_options_builder.rb +22 -0
  54. data/lib/ui_bibz/factory_methods/component_initialize_factory_method.rb +33 -0
  55. data/lib/ui_bibz/helpers/ui/core/boxes_helper.rb +12 -12
  56. data/lib/ui_bibz/helpers/ui/core/forms_helper.rb +50 -50
  57. data/lib/ui_bibz/helpers/ui/core/icons_helper.rb +6 -6
  58. data/lib/ui_bibz/helpers/ui/core/layouts_helper.rb +2 -2
  59. data/lib/ui_bibz/helpers/ui/core/lists_helper.rb +2 -2
  60. data/lib/ui_bibz/helpers/ui/core/navigations_helper.rb +12 -12
  61. data/lib/ui_bibz/helpers/ui/core/notifications_helper.rb +4 -4
  62. data/lib/ui_bibz/helpers/ui/core/windows_helper.rb +10 -2
  63. data/lib/ui_bibz/helpers/ui/ux_helper.rb +2 -2
  64. data/lib/ui_bibz/helpers/utils_helper.rb +2 -2
  65. data/lib/ui_bibz/infos.rb +3 -3
  66. data/lib/ui_bibz/inputs/ui_bibz_form/ui_bibz_form_builder.rb +12 -12
  67. data/lib/ui_bibz/inputs/ui_bibz_inputs/collection_input.rb +1 -1
  68. data/lib/ui_bibz/rails/engine.rb +21 -4
  69. data/lib/ui_bibz/strategies/component_initialize_abstract_strategy.rb +27 -0
  70. data/lib/ui_bibz/strategies/component_initialize_block_strategy.rb +31 -0
  71. data/lib/ui_bibz/strategies/component_initialize_hash_strategy.rb +18 -0
  72. data/lib/ui_bibz/strategies/component_initialize_standard_strategy.rb +18 -0
  73. data/lib/ui_bibz/ui/concerns/card_itemable_concern.rb +4 -4
  74. data/lib/ui_bibz/ui/concerns/notification_concern.rb +1 -1
  75. data/lib/ui_bibz/ui/core/boxes/card.rb +1 -1
  76. data/lib/ui_bibz/ui/core/boxes/card_accordion.rb +4 -4
  77. data/lib/ui_bibz/ui/core/boxes/card_column.rb +1 -1
  78. data/lib/ui_bibz/ui/core/boxes/card_deck.rb +1 -1
  79. data/lib/ui_bibz/ui/core/boxes/card_grid.rb +0 -3
  80. data/lib/ui_bibz/ui/core/boxes/card_group.rb +1 -1
  81. data/lib/ui_bibz/ui/core/boxes/components/card_body.rb +9 -9
  82. data/lib/ui_bibz/ui/core/boxes/components/card_col.rb +2 -2
  83. data/lib/ui_bibz/ui/core/boxes/components/card_list_group.rb +1 -1
  84. data/lib/ui_bibz/ui/core/boxes/components/card_row.rb +1 -1
  85. data/lib/ui_bibz/ui/core/component.rb +13 -62
  86. data/lib/ui_bibz/ui/core/forms/buttons/button.rb +3 -1
  87. data/lib/ui_bibz/ui/core/forms/buttons/button_group.rb +11 -11
  88. data/lib/ui_bibz/ui/core/forms/choices/box_switch_field.rb +7 -7
  89. data/lib/ui_bibz/ui/core/forms/choices/checkbox_field.rb +2 -2
  90. data/lib/ui_bibz/ui/core/forms/choices/choice_group.rb +5 -6
  91. data/lib/ui_bibz/ui/core/forms/choices/components/choice.rb +1 -1
  92. data/lib/ui_bibz/ui/core/forms/dates/date_picker_field.rb +15 -15
  93. data/lib/ui_bibz/ui/core/forms/dropdowns/components/dropdown_link.rb +1 -1
  94. data/lib/ui_bibz/ui/core/forms/dropdowns/dropdown.rb +5 -5
  95. data/lib/ui_bibz/ui/core/forms/numbers/slider_field.rb +1 -1
  96. data/lib/ui_bibz/ui/core/forms/selects/dropdown_select_field.rb +10 -10
  97. data/lib/ui_bibz/ui/core/forms/selects/multi_column_field.rb +2 -2
  98. data/lib/ui_bibz/ui/core/forms/surrounds/surround_field.rb +32 -32
  99. data/lib/ui_bibz/ui/core/forms/textareas/markdown_editor_field.rb +7 -8
  100. data/lib/ui_bibz/ui/core/icons/components/glyph_text.rb +1 -1
  101. data/lib/ui_bibz/ui/core/icons/glyph.rb +4 -3
  102. data/lib/ui_bibz/ui/core/layouts/row.rb +2 -2
  103. data/lib/ui_bibz/ui/core/lists/components/list.rb +4 -4
  104. data/lib/ui_bibz/ui/core/lists/list_group.rb +1 -1
  105. data/lib/ui_bibz/ui/core/navigations/breadcrumb.rb +6 -4
  106. data/lib/ui_bibz/ui/core/navigations/components/nav_link_span.rb +1 -2
  107. data/lib/ui_bibz/ui/core/navigations/components/navbar_form.rb +6 -5
  108. data/lib/ui_bibz/ui/core/navigations/components/toolbar_form.rb +2 -2
  109. data/lib/ui_bibz/ui/core/navigations/nav.rb +10 -6
  110. data/lib/ui_bibz/ui/core/navigations/navbar.rb +21 -19
  111. data/lib/ui_bibz/ui/core/navigations/pagination.rb +3 -3
  112. data/lib/ui_bibz/ui/core/navigations/toolbar.rb +5 -5
  113. data/lib/ui_bibz/ui/core/notifications/alert.rb +4 -5
  114. data/lib/ui_bibz/ui/core/notifications/badge.rb +6 -2
  115. data/lib/ui_bibz/ui/core/notifications/components/toast_header.rb +1 -1
  116. data/lib/ui_bibz/ui/core/notifications/progress_bar.rb +3 -3
  117. data/lib/ui_bibz/ui/core/notifications/toast.rb +8 -9
  118. data/lib/ui_bibz/ui/core/windows/components/offcanvas_body.rb +47 -0
  119. data/lib/ui_bibz/ui/core/windows/components/offcanvas_header.rb +54 -0
  120. data/lib/ui_bibz/ui/core/windows/modal.rb +9 -9
  121. data/lib/ui_bibz/ui/core/windows/offcanvas.rb +84 -0
  122. data/lib/ui_bibz/ui/extensions/core/component/glyph_extension.rb +4 -20
  123. data/lib/ui_bibz/ui/extensions/core/component/klass_extension.rb +11 -19
  124. data/lib/ui_bibz/ui/extensions/core/forms/connect_extension.rb +1 -1
  125. data/lib/ui_bibz/ui/ux/containers/components/panel_column.rb +3 -3
  126. data/lib/ui_bibz/ui/ux/containers/components/panel_deck.rb +3 -3
  127. data/lib/ui_bibz/ui/ux/containers/components/panel_group.rb +3 -3
  128. data/lib/ui_bibz/ui/ux/containers/components/panel_header.rb +4 -4
  129. data/lib/ui_bibz/ui/ux/containers/panel.rb +13 -13
  130. data/lib/ui_bibz/ui/ux/tables/components/actions.rb +4 -4
  131. data/lib/ui_bibz/ui/ux/tables/components/column.rb +1 -1
  132. data/lib/ui_bibz/ui/ux/tables/components/columns.rb +2 -2
  133. data/lib/ui_bibz/ui/ux/tables/extensions/sortable.rb +1 -1
  134. data/lib/ui_bibz/ui/ux/tables/table.rb +5 -5
  135. data/lib/ui_bibz/ui/ux/tables/table_card.rb +6 -6
  136. data/lib/ui_bibz/ui/ux/tables/table_search_field.rb +1 -1
  137. data/lib/ui_bibz/utils/breakdown_class_name_generator.rb +3 -3
  138. data/lib/ui_bibz/utils/screwdriver.rb +1 -1
  139. data/lib/ui_bibz/view_objects/glyph_component_view_object.rb +38 -0
  140. data/lib/ui_bibz.rb +25 -0
  141. data/test/builders/data_html_classes_builder_test.rb +37 -0
  142. data/test/builders/html_classes_builder_test.rb +76 -0
  143. data/test/dummy/Rakefile +1 -1
  144. data/test/dummy/app/assets/stylesheets/application.css +1 -15
  145. data/test/dummy/app/channels/application_cable/channel.rb +6 -0
  146. data/test/dummy/app/channels/application_cable/connection.rb +6 -0
  147. data/test/dummy/app/jobs/application_job.rb +9 -0
  148. data/test/dummy/app/mailers/application_mailer.rb +6 -0
  149. data/test/dummy/app/views/layouts/application.html.erb +10 -12
  150. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  151. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  152. data/test/dummy/bin/rails +3 -3
  153. data/test/dummy/bin/rake +2 -2
  154. data/test/dummy/bin/setup +12 -12
  155. data/test/dummy/config/application.rb +13 -17
  156. data/test/dummy/config/boot.rb +3 -3
  157. data/test/dummy/config/database.yml +2 -2
  158. data/test/dummy/config/environment.rb +1 -1
  159. data/test/dummy/config/environments/development.rb +21 -16
  160. data/test/dummy/config/environments/production.rb +16 -41
  161. data/test/dummy/config/environments/test.rb +19 -8
  162. data/test/dummy/config/importmap.rb +11 -0
  163. data/test/dummy/config/initializers/content_security_policy.rb +21 -24
  164. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -2
  165. data/test/dummy/config/initializers/inflections.rb +4 -4
  166. data/test/dummy/config/initializers/permissions_policy.rb +12 -0
  167. data/test/dummy/config/locales/en.yml +13 -3
  168. data/test/dummy/config/puma.rb +7 -2
  169. data/test/dummy/config/storage.yml +5 -5
  170. data/test/dummy/config.ru +2 -1
  171. data/test/simple_form_test.rb +24 -24
  172. data/test/ui/core/boxes/card_test.rb +2 -1
  173. data/test/ui/core/component_test.rb +2 -2
  174. data/test/ui/core/forms/buttons/button_group_test.rb +1 -1
  175. data/test/ui/core/forms/buttons/button_link_test.rb +1 -1
  176. data/test/ui/core/forms/buttons/button_refresh_test.rb +1 -1
  177. data/test/ui/core/forms/buttons/button_test.rb +2 -2
  178. data/test/ui/core/forms/choices/box_switch_field_test.rb +10 -10
  179. data/test/ui/core/forms/choices/checkbox_field_test.rb +1 -1
  180. data/test/ui/core/forms/choices/choice_group_test.rb +1 -1
  181. data/test/ui/core/forms/dropdowns/dropdown_test.rb +1 -1
  182. data/test/ui/core/forms/numbers/formula_field_test.rb +1 -1
  183. data/test/ui/core/forms/selects/dropdown_select_field_test.rb +2 -2
  184. data/test/ui/core/forms/selects/select_field_test.rb +1 -1
  185. data/test/ui/core/forms/surrounds/surround_field_test.rb +4 -4
  186. data/test/ui/core/forms/texts/auto_complete_field_test.rb +2 -2
  187. data/test/ui/core/icons/glyph_test.rb +8 -4
  188. data/test/ui/core/icons/star_test.rb +12 -6
  189. data/test/ui/core/navigations/breadcrumb_test.rb +1 -1
  190. data/test/ui/core/navigations/link_test.rb +1 -1
  191. data/test/ui/core/navigations/nav_test.rb +11 -0
  192. data/test/ui/core/notifications/alert_test.rb +1 -1
  193. data/test/ui/core/notifications/badge_test.rb +3 -3
  194. data/test/ui/core/notifications/popover_test.rb +4 -4
  195. data/test/ui/core/notifications/spinner_test.rb +1 -1
  196. data/test/ui/core/notifications/toast_test.rb +1 -1
  197. data/test/ui/core/notifications/tooltip_test.rb +4 -4
  198. data/test/ui/core/windows/offcanvas_test.rb +27 -0
  199. data/test/ui/ux/containers/panel_test.rb +1 -1
  200. data/test/ui/ux/tables/table_test.rb +3 -3
  201. data/test/view_objects/glyph_component_view_object_test.rb +17 -0
  202. data/ui_bibz.gemspec +6 -20
  203. data/vendor/assets/fonts/fontawesome/fa-brands-400.ttf +0 -0
  204. data/vendor/assets/fonts/fontawesome/fa-brands-400.woff2 +0 -0
  205. data/vendor/assets/fonts/fontawesome/fa-regular-400.ttf +0 -0
  206. data/vendor/assets/fonts/fontawesome/fa-regular-400.woff2 +0 -0
  207. data/vendor/assets/fonts/fontawesome/fa-solid-900.ttf +0 -0
  208. data/vendor/assets/fonts/fontawesome/fa-solid-900.woff2 +0 -0
  209. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.ttf +0 -0
  210. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.woff2 +0 -0
  211. data/vendor/assets/javascripts/bootstrap-markdown.js +1 -1555
  212. data/vendor/assets/javascripts/bootstrap-multiselect.min.js +40 -1176
  213. data/vendor/assets/javascripts/bootstrap-switch.min.js +9 -21
  214. data/vendor/assets/javascripts/bs-custom-file-input.min.js +0 -1
  215. data/vendor/assets/javascripts/fontawesome/all.js +5977 -0
  216. data/vendor/assets/javascripts/fontawesome/all.min.js +6 -0
  217. data/vendor/assets/javascripts/fontawesome/brands.js +749 -0
  218. data/vendor/assets/javascripts/fontawesome/brands.min.js +6 -0
  219. data/vendor/assets/javascripts/fontawesome/conflict-detection.js +1138 -0
  220. data/vendor/assets/javascripts/fontawesome/conflict-detection.min.js +6 -0
  221. data/vendor/assets/javascripts/fontawesome/fontawesome.js +3126 -0
  222. data/vendor/assets/javascripts/fontawesome/fontawesome.min.js +6 -0
  223. data/vendor/assets/javascripts/fontawesome/regular.js +445 -0
  224. data/vendor/assets/javascripts/fontawesome/regular.min.js +6 -0
  225. data/vendor/assets/javascripts/fontawesome/solid.js +1672 -0
  226. data/vendor/assets/javascripts/fontawesome/solid.min.js +6 -0
  227. data/vendor/assets/javascripts/fontawesome/v4-shims.js +225 -0
  228. data/vendor/assets/javascripts/fontawesome/v4-shims.min.js +6 -0
  229. data/vendor/assets/javascripts/fuzzysort.js +562 -0
  230. data/vendor/assets/javascripts/jquery-3.7.0.min.js +2 -0
  231. data/vendor/assets/javascripts/jquery.multi-select.min.js +725 -1
  232. data/vendor/assets/stylesheets/bootstrap-multiselect.sass +115 -0
  233. data/vendor/assets/stylesheets/bootstrap-switch.scss +211 -0
  234. data/vendor/assets/stylesheets/fontawesome/_animated.scss +142 -9
  235. data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +13 -13
  236. data/vendor/assets/stylesheets/fontawesome/_core.scss +28 -6
  237. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +2 -1
  238. data/vendor/assets/stylesheets/fontawesome/_functions.scss +57 -0
  239. data/vendor/assets/stylesheets/fontawesome/_icons.scss +7 -1438
  240. data/vendor/assets/stylesheets/fontawesome/_list.scss +4 -4
  241. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +53 -34
  242. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +25 -18
  243. data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +12 -3
  244. data/vendor/assets/stylesheets/fontawesome/_shims.scss +640 -664
  245. data/vendor/assets/stylesheets/fontawesome/_sizing.scss +16 -0
  246. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +5 -4
  247. data/vendor/assets/stylesheets/fontawesome/_variables.scss +4896 -1393
  248. data/vendor/assets/stylesheets/fontawesome/brands.scss +17 -10
  249. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +7 -2
  250. data/vendor/assets/stylesheets/fontawesome/regular.scss +13 -10
  251. data/vendor/assets/stylesheets/fontawesome/solid.scss +13 -11
  252. data/vendor/assets/stylesheets/fontawesome/v4-shims.scss +6 -1
  253. data/vendor/assets/stylesheets/multi-select.css +92 -0
  254. metadata +120 -348
  255. data/.gitlab-ci.yml +0 -17
  256. data/.travis.yml +0 -24
  257. data/lib/ui_bibz/ui/extensions/core/component/popover_extension.rb +0 -70
  258. data/structure.md +0 -68
  259. data/test/dummy/README.rdoc +0 -28
  260. data/test/dummy/app/assets/javascripts/application.js +0 -13
  261. data/test/dummy/app/javascripts/packs/index.js +0 -3
  262. data/test/dummy/config/initializers/application_controller_renderer.rb +0 -9
  263. data/test/dummy/config/initializers/assets.rb +0 -14
  264. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
  265. data/test/dummy/config/initializers/cookies_serializer.rb +0 -7
  266. data/test/dummy/config/initializers/mime_types.rb +0 -5
  267. data/test/dummy/config/initializers/session_store.rb +0 -5
  268. data/test/dummy/config/initializers/ui_bibz.rb +0 -5
  269. data/test/dummy/config/initializers/wrap_parameters.rb +0 -16
  270. data/test/dummy/config/secrets.yml +0 -22
  271. data/test/dummy/config/spring.rb +0 -8
  272. data/test/dummy/test/models/user_test.rb +0 -9
  273. data/vendor/assets/fonts/fa-brands-400.eot +0 -0
  274. data/vendor/assets/fonts/fa-brands-400.svg +0 -3570
  275. data/vendor/assets/fonts/fa-brands-400.ttf +0 -0
  276. data/vendor/assets/fonts/fa-brands-400.woff +0 -0
  277. data/vendor/assets/fonts/fa-brands-400.woff2 +0 -0
  278. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  279. data/vendor/assets/fonts/fa-regular-400.svg +0 -803
  280. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  281. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  282. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  283. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  284. data/vendor/assets/fonts/fa-solid-900.svg +0 -4938
  285. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  286. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  287. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  288. data/vendor/assets/javascripts/all.js +0 -4441
  289. data/vendor/assets/javascripts/all.min.js +0 -5
  290. data/vendor/assets/stylesheets/all.min.css +0 -5
  291. data/vendor/assets/stylesheets/fontawesome/_larger.scss +0 -23
  292. data/vendor/assets/stylesheets/svg-with-js.css +0 -5
  293. /data/{test/dummy/app/mailers/.keep → app/assets/stylesheets/sass/forms/_dropdown.sass} +0 -0
  294. /data/{test/dummy/app/views/users/index.html.erb → app/assets/stylesheets/sass/forms/_input_refresh_button.sass} +0 -0
@@ -0,0 +1,562 @@
1
+ // https://github.com/farzher/fuzzysort v2.0.4
2
+ /*
3
+ SublimeText-like Fuzzy Search
4
+
5
+ fuzzysort.single('fs', 'Fuzzy Search') // {score: -16}
6
+ fuzzysort.single('test', 'test') // {score: 0}
7
+ fuzzysort.single('doesnt exist', 'target') // null
8
+
9
+ fuzzysort.go('mr', [{file:'Monitor.cpp'}, {file:'MeshRenderer.cpp'}], {key:'file'})
10
+ // [{score:-18, obj:{file:'MeshRenderer.cpp'}}, {score:-6009, obj:{file:'Monitor.cpp'}}]
11
+
12
+ fuzzysort.go('mr', ['Monitor.cpp', 'MeshRenderer.cpp'])
13
+ // [{score: -18, target: "MeshRenderer.cpp"}, {score: -6009, target: "Monitor.cpp"}]
14
+
15
+ fuzzysort.highlight(fuzzysort.single('fs', 'Fuzzy Search'), '<b>', '</b>')
16
+ // <b>F</b>uzzy <b>S</b>earch
17
+ */
18
+
19
+ // UMD (Universal Module Definition) for fuzzysort
20
+ ;((root, UMD) => {
21
+ if(typeof define === 'function' && define.amd) define([], UMD)
22
+ else if(typeof module === 'object' && module.exports) module.exports = UMD()
23
+ else root['fuzzysort'] = UMD()
24
+ })(this || (typeof window !== 'undefined' ? window : global), _ => {
25
+ 'use strict'
26
+
27
+ var single = (search, target) => { if(search=='farzher')return{target:"farzher was here (^-^*)/",score:0,_indexes:[0]}
28
+ if(!search || !target) return NULL
29
+
30
+ var preparedSearch = getPreparedSearch(search)
31
+ if(!isObj(target)) target = getPrepared(target)
32
+
33
+ var searchBitflags = preparedSearch.bitflags
34
+ if((searchBitflags & target._bitflags) !== searchBitflags) return NULL
35
+
36
+ return algorithm(preparedSearch, target)
37
+ }
38
+
39
+
40
+ var go = (search, targets, options) => { if(search=='farzher')return[{target:"farzher was here (^-^*)/",score:0,_indexes:[0],obj:targets?targets[0]:NULL}]
41
+ if(!search) return options&&options.all ? all(search, targets, options) : noResults
42
+
43
+ var preparedSearch = getPreparedSearch(search)
44
+ var searchBitflags = preparedSearch.bitflags
45
+ var containsSpace = preparedSearch.containsSpace
46
+
47
+ var threshold = options&&options.threshold || INT_MIN
48
+ var limit = options&&options['limit'] || INT_MAX // for some reason only limit breaks when minified
49
+
50
+ var resultsLen = 0; var limitedCount = 0
51
+ var targetsLen = targets.length
52
+
53
+ // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]
54
+
55
+ // options.key
56
+ if(options && options.key) {
57
+ var key = options.key
58
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
59
+ var target = getValue(obj, key)
60
+ if(!target) continue
61
+ if(!isObj(target)) target = getPrepared(target)
62
+
63
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
64
+ var result = algorithm(preparedSearch, target)
65
+ if(result === NULL) continue
66
+ if(result.score < threshold) continue
67
+
68
+ // have to clone result so duplicate targets from different obj can each reference the correct obj
69
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:result.score, _indexes:result._indexes, obj:obj} // hidden
70
+
71
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
72
+ else {
73
+ ++limitedCount
74
+ if(result.score > q.peek().score) q.replaceTop(result)
75
+ }
76
+ }
77
+
78
+ // options.keys
79
+ } else if(options && options.keys) {
80
+ var scoreFn = options['scoreFn'] || defaultScoreFn
81
+ var keys = options.keys
82
+ var keysLen = keys.length
83
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
84
+ var objResults = new Array(keysLen)
85
+ for (var keyI = 0; keyI < keysLen; ++keyI) {
86
+ var key = keys[keyI]
87
+ var target = getValue(obj, key)
88
+ if(!target) { objResults[keyI] = NULL; continue }
89
+ if(!isObj(target)) target = getPrepared(target)
90
+
91
+ if((searchBitflags & target._bitflags) !== searchBitflags) objResults[keyI] = NULL
92
+ else objResults[keyI] = algorithm(preparedSearch, target)
93
+ }
94
+ objResults.obj = obj // before scoreFn so scoreFn can use it
95
+ var score = scoreFn(objResults)
96
+ if(score === NULL) continue
97
+ if(score < threshold) continue
98
+ objResults.score = score
99
+ if(resultsLen < limit) { q.add(objResults); ++resultsLen }
100
+ else {
101
+ ++limitedCount
102
+ if(score > q.peek().score) q.replaceTop(objResults)
103
+ }
104
+ }
105
+
106
+ // no keys
107
+ } else {
108
+ for(var i = 0; i < targetsLen; ++i) { var target = targets[i]
109
+ if(!target) continue
110
+ if(!isObj(target)) target = getPrepared(target)
111
+
112
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
113
+ var result = algorithm(preparedSearch, target)
114
+ if(result === NULL) continue
115
+ if(result.score < threshold) continue
116
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
117
+ else {
118
+ ++limitedCount
119
+ if(result.score > q.peek().score) q.replaceTop(result)
120
+ }
121
+ }
122
+ }
123
+
124
+ if(resultsLen === 0) return noResults
125
+ var results = new Array(resultsLen)
126
+ for(var i = resultsLen - 1; i >= 0; --i) results[i] = q.poll()
127
+ results.total = resultsLen + limitedCount
128
+ return results
129
+ }
130
+
131
+
132
+ var highlight = (result, hOpen, hClose) => {
133
+ if(typeof hOpen === 'function') return highlightCallback(result, hOpen)
134
+ if(result === NULL) return NULL
135
+ if(hOpen === undefined) hOpen = '<b>'
136
+ if(hClose === undefined) hClose = '</b>'
137
+ var highlighted = ''
138
+ var matchesIndex = 0
139
+ var opened = false
140
+ var target = result.target
141
+ var targetLen = target.length
142
+ var indexes = result._indexes
143
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
144
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
145
+ if(indexes[matchesIndex] === i) {
146
+ ++matchesIndex
147
+ if(!opened) { opened = true
148
+ highlighted += hOpen
149
+ }
150
+
151
+ if(matchesIndex === indexes.length) {
152
+ highlighted += char + hClose + target.substr(i+1)
153
+ break
154
+ }
155
+ } else {
156
+ if(opened) { opened = false
157
+ highlighted += hClose
158
+ }
159
+ }
160
+ highlighted += char
161
+ }
162
+
163
+ return highlighted
164
+ }
165
+ var highlightCallback = (result, cb) => {
166
+ if(result === NULL) return NULL
167
+ var target = result.target
168
+ var targetLen = target.length
169
+ var indexes = result._indexes
170
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
171
+ var highlighted = ''
172
+ var matchI = 0
173
+ var indexesI = 0
174
+ var opened = false
175
+ var result = []
176
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
177
+ if(indexes[indexesI] === i) {
178
+ ++indexesI
179
+ if(!opened) { opened = true
180
+ result.push(highlighted); highlighted = ''
181
+ }
182
+
183
+ if(indexesI === indexes.length) {
184
+ highlighted += char
185
+ result.push(cb(highlighted, matchI++)); highlighted = ''
186
+ result.push(target.substr(i+1))
187
+ break
188
+ }
189
+ } else {
190
+ if(opened) { opened = false
191
+ result.push(cb(highlighted, matchI++)); highlighted = ''
192
+ }
193
+ }
194
+ highlighted += char
195
+ }
196
+ return result
197
+ }
198
+
199
+
200
+ var indexes = result => result._indexes.slice(0, result._indexes.len).sort((a,b)=>a-b)
201
+
202
+
203
+ var prepare = (target) => {
204
+ if(typeof target !== 'string') target = ''
205
+ var info = prepareLowerInfo(target)
206
+ return {'target':target, _targetLower:info._lower, _targetLowerCodes:info.lowerCodes, _nextBeginningIndexes:NULL, _bitflags:info.bitflags, 'score':NULL, _indexes:[0], 'obj':NULL} // hidden
207
+ }
208
+
209
+
210
+ // Below this point is only internal code
211
+ // Below this point is only internal code
212
+ // Below this point is only internal code
213
+ // Below this point is only internal code
214
+
215
+
216
+ var prepareSearch = (search) => {
217
+ if(typeof search !== 'string') search = ''
218
+ search = search.trim()
219
+ var info = prepareLowerInfo(search)
220
+
221
+ var spaceSearches = []
222
+ if(info.containsSpace) {
223
+ var searches = search.split(/\s+/)
224
+ searches = [...new Set(searches)] // distinct
225
+ for(var i=0; i<searches.length; i++) {
226
+ if(searches[i] === '') continue
227
+ var _info = prepareLowerInfo(searches[i])
228
+ spaceSearches.push({lowerCodes:_info.lowerCodes, _lower:searches[i].toLowerCase(), containsSpace:false})
229
+ }
230
+ }
231
+
232
+ return {lowerCodes: info.lowerCodes, bitflags: info.bitflags, containsSpace: info.containsSpace, _lower: info._lower, spaceSearches: spaceSearches}
233
+ }
234
+
235
+
236
+
237
+ var getPrepared = (target) => {
238
+ if(target.length > 999) return prepare(target) // don't cache huge targets
239
+ var targetPrepared = preparedCache.get(target)
240
+ if(targetPrepared !== undefined) return targetPrepared
241
+ targetPrepared = prepare(target)
242
+ preparedCache.set(target, targetPrepared)
243
+ return targetPrepared
244
+ }
245
+ var getPreparedSearch = (search) => {
246
+ if(search.length > 999) return prepareSearch(search) // don't cache huge searches
247
+ var searchPrepared = preparedSearchCache.get(search)
248
+ if(searchPrepared !== undefined) return searchPrepared
249
+ searchPrepared = prepareSearch(search)
250
+ preparedSearchCache.set(search, searchPrepared)
251
+ return searchPrepared
252
+ }
253
+
254
+
255
+ var all = (search, targets, options) => {
256
+ var results = []; results.total = targets.length
257
+
258
+ var limit = options && options.limit || INT_MAX
259
+
260
+ if(options && options.key) {
261
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
262
+ var target = getValue(obj, options.key)
263
+ if(!target) continue
264
+ if(!isObj(target)) target = getPrepared(target)
265
+ target.score = INT_MIN
266
+ target._indexes.len = 0
267
+ var result = target
268
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:target.score, _indexes:NULL, obj:obj} // hidden
269
+ results.push(result); if(results.length >= limit) return results
270
+ }
271
+ } else if(options && options.keys) {
272
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
273
+ var objResults = new Array(options.keys.length)
274
+ for (var keyI = options.keys.length - 1; keyI >= 0; --keyI) {
275
+ var target = getValue(obj, options.keys[keyI])
276
+ if(!target) { objResults[keyI] = NULL; continue }
277
+ if(!isObj(target)) target = getPrepared(target)
278
+ target.score = INT_MIN
279
+ target._indexes.len = 0
280
+ objResults[keyI] = target
281
+ }
282
+ objResults.obj = obj
283
+ objResults.score = INT_MIN
284
+ results.push(objResults); if(results.length >= limit) return results
285
+ }
286
+ } else {
287
+ for(var i=0;i<targets.length;i++) { var target = targets[i]
288
+ if(!target) continue
289
+ if(!isObj(target)) target = getPrepared(target)
290
+ target.score = INT_MIN
291
+ target._indexes.len = 0
292
+ results.push(target); if(results.length >= limit) return results
293
+ }
294
+ }
295
+
296
+ return results
297
+ }
298
+
299
+
300
+ var algorithm = (preparedSearch, prepared, allowSpaces=false) => {
301
+ if(allowSpaces===false && preparedSearch.containsSpace) return algorithmSpaces(preparedSearch, prepared)
302
+
303
+ var searchLower = preparedSearch._lower
304
+ var searchLowerCodes = preparedSearch.lowerCodes
305
+ var searchLowerCode = searchLowerCodes[0]
306
+ var targetLowerCodes = prepared._targetLowerCodes
307
+ var searchLen = searchLowerCodes.length
308
+ var targetLen = targetLowerCodes.length
309
+ var searchI = 0 // where we at
310
+ var targetI = 0 // where you at
311
+ var matchesSimpleLen = 0
312
+
313
+ // very basic fuzzy match; to remove non-matching targets ASAP!
314
+ // walk through target. find sequential matches.
315
+ // if all chars aren't found then exit
316
+ for(;;) {
317
+ var isMatch = searchLowerCode === targetLowerCodes[targetI]
318
+ if(isMatch) {
319
+ matchesSimple[matchesSimpleLen++] = targetI
320
+ ++searchI; if(searchI === searchLen) break
321
+ searchLowerCode = searchLowerCodes[searchI]
322
+ }
323
+ ++targetI; if(targetI >= targetLen) return NULL // Failed to find searchI
324
+ }
325
+
326
+ var searchI = 0
327
+ var successStrict = false
328
+ var matchesStrictLen = 0
329
+
330
+ var nextBeginningIndexes = prepared._nextBeginningIndexes
331
+ if(nextBeginningIndexes === NULL) nextBeginningIndexes = prepared._nextBeginningIndexes = prepareNextBeginningIndexes(prepared.target)
332
+ var firstPossibleI = targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1]
333
+
334
+ // Our target string successfully matched all characters in sequence!
335
+ // Let's try a more advanced and strict test to improve the score
336
+ // only count it as a match if it's consecutive or a beginning character!
337
+ var backtrackCount = 0
338
+ if(targetI !== targetLen) for(;;) {
339
+ if(targetI >= targetLen) {
340
+ // We failed to find a good spot for this search char, go back to the previous search char and force it forward
341
+ if(searchI <= 0) break // We failed to push chars forward for a better match
342
+
343
+ ++backtrackCount; if(backtrackCount > 200) break // exponential backtracking is taking too long, just give up and return a bad match
344
+
345
+ --searchI
346
+ var lastMatch = matchesStrict[--matchesStrictLen]
347
+ targetI = nextBeginningIndexes[lastMatch]
348
+
349
+ } else {
350
+ var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI]
351
+ if(isMatch) {
352
+ matchesStrict[matchesStrictLen++] = targetI
353
+ ++searchI; if(searchI === searchLen) { successStrict = true; break }
354
+ ++targetI
355
+ } else {
356
+ targetI = nextBeginningIndexes[targetI]
357
+ }
358
+ }
359
+ }
360
+
361
+ // check if it's a substring match
362
+ var substringIndex = prepared._targetLower.indexOf(searchLower, matchesSimple[0]) // perf: this is slow
363
+ var isSubstring = ~substringIndex
364
+ if(isSubstring && !successStrict) { // rewrite the indexes from basic to the substring
365
+ for(var i=0; i<matchesSimpleLen; ++i) matchesSimple[i] = substringIndex+i
366
+ }
367
+ var isSubstringBeginning = false
368
+ if(isSubstring) {
369
+ isSubstringBeginning = prepared._nextBeginningIndexes[substringIndex-1] === substringIndex
370
+ }
371
+
372
+ { // tally up the score & keep track of matches for highlighting later
373
+ if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen }
374
+ else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen }
375
+
376
+ var score = 0
377
+
378
+ var extraMatchGroupCount = 0
379
+ for(var i = 1; i < searchLen; ++i) {
380
+ if(matchesBest[i] - matchesBest[i-1] !== 1) {score -= matchesBest[i]; ++extraMatchGroupCount}
381
+ }
382
+ var unmatchedDistance = matchesBest[searchLen-1] - matchesBest[0] - (searchLen-1)
383
+
384
+ score -= (12+unmatchedDistance) * extraMatchGroupCount // penality for more groups
385
+
386
+ if(matchesBest[0] !== 0) score -= matchesBest[0]*matchesBest[0]*.2 // penality for not starting near the beginning
387
+
388
+ if(!successStrict) {
389
+ score *= 1000
390
+ } else {
391
+ // successStrict on a target with too many beginning indexes loses points for being a bad target
392
+ var uniqueBeginningIndexes = 1
393
+ for(var i = nextBeginningIndexes[0]; i < targetLen; i=nextBeginningIndexes[i]) ++uniqueBeginningIndexes
394
+
395
+ if(uniqueBeginningIndexes > 24) score *= (uniqueBeginningIndexes-24)*10 // quite arbitrary numbers here ...
396
+ }
397
+
398
+ if(isSubstring) score /= 1+searchLen*searchLen*1 // bonus for being a full substring
399
+ if(isSubstringBeginning) score /= 1+searchLen*searchLen*1 // bonus for substring starting on a beginningIndex
400
+
401
+ score -= targetLen - searchLen // penality for longer targets
402
+ prepared.score = score
403
+
404
+ for(var i = 0; i < matchesBestLen; ++i) prepared._indexes[i] = matchesBest[i]
405
+ prepared._indexes.len = matchesBestLen
406
+
407
+ return prepared
408
+ }
409
+ }
410
+ var algorithmSpaces = (preparedSearch, target) => {
411
+ var seen_indexes = new Set()
412
+ var score = 0
413
+ var result = NULL
414
+
415
+ var first_seen_index_last_search = 0
416
+ var searches = preparedSearch.spaceSearches
417
+ for(var i=0; i<searches.length; ++i) {
418
+ var search = searches[i]
419
+
420
+ result = algorithm(search, target)
421
+ if(result === NULL) return NULL
422
+
423
+ score += result.score
424
+
425
+ // dock points based on order otherwise "c man" returns Manifest.cpp instead of CheatManager.h
426
+ if(result._indexes[0] < first_seen_index_last_search) {
427
+ score -= first_seen_index_last_search - result._indexes[0]
428
+ }
429
+ first_seen_index_last_search = result._indexes[0]
430
+
431
+ for(var j=0; j<result._indexes.len; ++j) seen_indexes.add(result._indexes[j])
432
+ }
433
+
434
+ // allows a search with spaces that's an exact substring to score well
435
+ var allowSpacesResult = algorithm(preparedSearch, target, /*allowSpaces=*/true)
436
+ if(allowSpacesResult !== NULL && allowSpacesResult.score > score) {
437
+ return allowSpacesResult
438
+ }
439
+
440
+ result.score = score
441
+
442
+ var i = 0
443
+ for (let index of seen_indexes) result._indexes[i++] = index
444
+ result._indexes.len = i
445
+
446
+ return result
447
+ }
448
+
449
+
450
+ var prepareLowerInfo = (str) => {
451
+ var strLen = str.length
452
+ var lower = str.toLowerCase()
453
+ var lowerCodes = [] // new Array(strLen) sparse array is too slow
454
+ var bitflags = 0
455
+ var containsSpace = false // space isn't stored in bitflags because of how searching with a space works
456
+
457
+ for(var i = 0; i < strLen; ++i) {
458
+ var lowerCode = lowerCodes[i] = lower.charCodeAt(i)
459
+
460
+ if(lowerCode === 32) {
461
+ containsSpace = true
462
+ continue // it's important that we don't set any bitflags for space
463
+ }
464
+
465
+ var bit = lowerCode>=97&&lowerCode<=122 ? lowerCode-97 // alphabet
466
+ : lowerCode>=48&&lowerCode<=57 ? 26 // numbers
467
+ // 3 bits available
468
+ : lowerCode<=127 ? 30 // other ascii
469
+ : 31 // other utf8
470
+ bitflags |= 1<<bit
471
+ }
472
+
473
+ return {lowerCodes:lowerCodes, bitflags:bitflags, containsSpace:containsSpace, _lower:lower}
474
+ }
475
+ var prepareBeginningIndexes = (target) => {
476
+ var targetLen = target.length
477
+ var beginningIndexes = []; var beginningIndexesLen = 0
478
+ var wasUpper = false
479
+ var wasAlphanum = false
480
+ for(var i = 0; i < targetLen; ++i) {
481
+ var targetCode = target.charCodeAt(i)
482
+ var isUpper = targetCode>=65&&targetCode<=90
483
+ var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57
484
+ var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum
485
+ wasUpper = isUpper
486
+ wasAlphanum = isAlphanum
487
+ if(isBeginning) beginningIndexes[beginningIndexesLen++] = i
488
+ }
489
+ return beginningIndexes
490
+ }
491
+ var prepareNextBeginningIndexes = (target) => {
492
+ var targetLen = target.length
493
+ var beginningIndexes = prepareBeginningIndexes(target)
494
+ var nextBeginningIndexes = [] // new Array(targetLen) sparse array is too slow
495
+ var lastIsBeginning = beginningIndexes[0]
496
+ var lastIsBeginningI = 0
497
+ for(var i = 0; i < targetLen; ++i) {
498
+ if(lastIsBeginning > i) {
499
+ nextBeginningIndexes[i] = lastIsBeginning
500
+ } else {
501
+ lastIsBeginning = beginningIndexes[++lastIsBeginningI]
502
+ nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning
503
+ }
504
+ }
505
+ return nextBeginningIndexes
506
+ }
507
+
508
+
509
+ var cleanup = () => { preparedCache.clear(); preparedSearchCache.clear(); matchesSimple = []; matchesStrict = [] }
510
+
511
+ var preparedCache = new Map()
512
+ var preparedSearchCache = new Map()
513
+ var matchesSimple = []; var matchesStrict = []
514
+
515
+
516
+ // for use with keys. just returns the maximum score
517
+ var defaultScoreFn = (a) => {
518
+ var max = INT_MIN
519
+ var len = a.length
520
+ for (var i = 0; i < len; ++i) {
521
+ var result = a[i]; if(result === NULL) continue
522
+ var score = result.score
523
+ if(score > max) max = score
524
+ }
525
+ if(max === INT_MIN) return NULL
526
+ return max
527
+ }
528
+
529
+ // prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop]
530
+ // prop = 'key1.key2' 10ms
531
+ // prop = ['key1', 'key2'] 27ms
532
+ var getValue = (obj, prop) => {
533
+ var tmp = obj[prop]; if(tmp !== undefined) return tmp
534
+ var segs = prop
535
+ if(!Array.isArray(prop)) segs = prop.split('.')
536
+ var len = segs.length
537
+ var i = -1
538
+ while (obj && (++i < len)) obj = obj[segs[i]]
539
+ return obj
540
+ }
541
+
542
+ var isObj = (x) => { return typeof x === 'object' } // faster as a function
543
+ // var INT_MAX = 9007199254740991; var INT_MIN = -INT_MAX
544
+ var INT_MAX = Infinity; var INT_MIN = -INT_MAX
545
+ var noResults = []; noResults.total = 0
546
+ var NULL = null
547
+
548
+
549
+ // Hacked version of https://github.com/lemire/FastPriorityQueue.js
550
+ var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c<o;){var s=c+1;a=c,s<o&&e[s].score<e[c].score&&(a=s),e[a-1>>1]=e[a],c=1+(a<<1)}for(var f=a-1>>1;a>0&&v.score<e[f].score;f=(a=f)-1>>1)e[a]=e[f];e[a]=v};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r.score<e[v].score;v=(a=v)-1>>1)e[a]=e[v];e[a]=r}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v()}),a}
551
+ var q = fastpriorityqueue() // reuse this
552
+
553
+
554
+ // fuzzysort is written this way for minification. all names are mangeled unless quoted
555
+ return {'single':single, 'go':go, 'highlight':highlight, 'prepare':prepare, 'indexes':indexes, 'cleanup':cleanup}
556
+ }) // UMD
557
+
558
+ // TODO: (feature) frecency
559
+ // TODO: (perf) use different sorting algo depending on the # of results?
560
+ // TODO: (perf) preparedCache is a memory leak
561
+ // TODO: (like sublime) backslash === forwardslash
562
+ // TODO: (perf) prepareSearch seems slow