mirror of
https://github.com/alex-shpak/hugo-book.git
synced 2025-06-09 10:24:05 +00:00
feat search box (#1)
* feat search box * replace flexshearch with lunrjs cause fuzzy + highlight * add svg search. Add infinity scroll to avoid creating a new page. Add some comments
This commit is contained in:
parent
132b7eb9e1
commit
d94e72e18d
@ -1,5 +1,6 @@
|
|||||||
# Hugo Book Theme
|
# Hugo Book Theme
|
||||||
|
|
||||||
|
|
||||||
[](https://gohugo.io)
|
[](https://gohugo.io)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||

|

|
||||||
|
@ -244,11 +244,65 @@ body[dir="rtl"] .book-menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.book-search {
|
.book-search {
|
||||||
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: $padding-16 0;
|
margin: $padding-16 0;
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
|
#book-search-input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
img {
|
||||||
|
z-index: 5;
|
||||||
|
position: absolute;
|
||||||
|
left: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#search-overlay {
|
||||||
|
background-color: #000;
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 0.1;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
#book-search-results {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
#book-search-hits {
|
||||||
|
overflow-y: scroll;
|
||||||
|
max-height: calc(100vh - 130px); // 130px -> uitopbar + content topbar
|
||||||
|
background-color: var(--body-background);
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 16px 32px 16px rgba(0, 0, 0, 0.16);
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 16px;
|
||||||
|
position: relative;
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
li {
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 10px;
|
||||||
|
h4 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--body-font-color);
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--gray-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
z-index: 4;
|
||||||
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 7px 20px 7px 48px;
|
padding: 7px 20px 7px 48px;
|
||||||
|
|
||||||
@ -303,14 +357,6 @@ body[dir="rtl"] .book-menu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#book-search-results {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 9999;
|
|
||||||
background: cyan;
|
|
||||||
li {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile-breakpoint) {
|
@media screen and (min-width: $mobile-breakpoint) {
|
||||||
.book-search {
|
.book-search {
|
||||||
|
145
assets/search.js
145
assets/search.js
@ -2,29 +2,29 @@
|
|||||||
|
|
||||||
{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
|
{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
|
||||||
{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }}
|
{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }}
|
||||||
{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }}
|
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
const searchDataURL = '{{ $searchData.RelPermalink }}';
|
const searchDataURL = '{{ $searchData.RelPermalink }}';
|
||||||
const indexConfig = Object.assign({{ $searchConfig }}, {
|
const input = document.querySelector('#book-search-input input');
|
||||||
doc: {
|
const searchOverlay = document.querySelector('#search-overlay')
|
||||||
id: 'id',
|
const resultsContainer = document.querySelector('#book-search-hits');
|
||||||
field: ['title', 'content'],
|
const results = document.querySelector('#book-search-results ul');
|
||||||
store: ['title', 'href', 'section']
|
const LIMIT_RESULTS = Infinity
|
||||||
}
|
const MIN_INPUT_SIZE = 2 // SDK ✅
|
||||||
});
|
const documents = new Map()
|
||||||
|
|
||||||
const input = document.querySelector('#book-search-input');
|
|
||||||
const results = document.querySelector('#book-search-results');
|
|
||||||
|
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listeners
|
||||||
input.addEventListener('focus', init);
|
input.addEventListener('focus', init);
|
||||||
input.addEventListener('keyup', search);
|
input.addEventListener('keyup', search);
|
||||||
|
|
||||||
document.addEventListener('keypress', focusSearchFieldOnKeyPress);
|
document.addEventListener('keypress', focusSearchFieldOnKeyPress);
|
||||||
|
searchOverlay.addEventListener('click', () => {
|
||||||
|
hideSearchBox()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Event} event
|
* @param {Event} event
|
||||||
@ -59,39 +59,114 @@
|
|||||||
function init() {
|
function init() {
|
||||||
input.removeEventListener('focus', init); // init once
|
input.removeEventListener('focus', init); // init once
|
||||||
input.required = true;
|
input.required = true;
|
||||||
|
|
||||||
fetch(searchDataURL)
|
fetch(searchDataURL)
|
||||||
.then(pages => pages.json())
|
.then(pages => pages.json())
|
||||||
.then(pages => {
|
.then(pages => {
|
||||||
window.bookSearchIndex = FlexSearch.create('balance', indexConfig);
|
window.lunrIdx = lunr(function() {
|
||||||
window.bookSearchIndex.add(pages);
|
this.ref('id')
|
||||||
|
this.field('id')
|
||||||
|
this.field('content')
|
||||||
|
this.field('href')
|
||||||
|
this.metadataWhitelist = ['position']
|
||||||
|
for (const page of pages) {
|
||||||
|
documents.set(page.id, page)
|
||||||
|
this.add(page);
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(() => input.required = false)
|
.then(() => input.required = false)
|
||||||
.then(search);
|
.then(search);
|
||||||
}
|
}
|
||||||
|
|
||||||
function search() {
|
function search() {
|
||||||
|
const value = input.value?.trim()
|
||||||
|
if (input.required) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
while (results.firstChild) {
|
while (results.firstChild) {
|
||||||
results.removeChild(results.firstChild);
|
results.removeChild(results.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!input.value) {
|
if (!value || value.length <= MIN_INPUT_SIZE) {
|
||||||
|
hideSearchBox()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchHits = window.bookSearchIndex.search(input.value, 10);
|
function searchValue(fuzzy) {
|
||||||
searchHits.forEach(function (page) {
|
// Operators:
|
||||||
const li = element('<li><a href></a><small></small></li>');
|
// +: means AND. i.e +sdk +metaverse will found words that contains sdk & metaverse
|
||||||
const a = li.querySelector('a'), small = li.querySelector('small');
|
// ~n: looks for N fuzzy words. i.e. metaverse~1 => metavese ✅
|
||||||
|
return value.split(' ').map(val => {
|
||||||
|
// Avoid blankspaces
|
||||||
|
if (!val) return
|
||||||
|
// if its a short word or fuzzy option is turned off, then return only the value with the +operator
|
||||||
|
if (val.length <= 4 || !fuzzy) return `+${val}`
|
||||||
|
|
||||||
a.href = page.href;
|
return `+${val}~1`
|
||||||
a.textContent = page.title;
|
}).filter(a => !!a).join(' ')
|
||||||
small.textContent = page.section;
|
}
|
||||||
|
|
||||||
results.appendChild(li);
|
function getSearchHits() {
|
||||||
|
// First search for the words without fuzzy, so we can have a more accurate result.
|
||||||
|
const hits = window.lunrIdx.search(searchValue()).slice(0, LIMIT_RESULTS);
|
||||||
|
if (hits.length) return hits
|
||||||
|
return window.lunrIdx.search(searchValue(true)).slice(0, LIMIT_RESULTS);
|
||||||
|
}
|
||||||
|
const searchHits = getSearchHits()
|
||||||
|
showSearchBox()
|
||||||
|
if (!searchHits.length) {
|
||||||
|
resultCard(`Not Found`, `Sorry, we couldn't find any matches. Try searching for a different keyword`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
searchHits.forEach((hit) => {
|
||||||
|
const document = documents.get(Number(hit.ref))
|
||||||
|
if (!document) return
|
||||||
|
const highlightedContent = highlightContent(document.content, hit)
|
||||||
|
resultCard(document.title, highlightedContent, document.href)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resultCard(title, content, href) {
|
||||||
|
const li = element('<li><a href><h4></h4><span></span></a></li>');
|
||||||
|
if (href) li.querySelector('a').href = href;
|
||||||
|
li.querySelector('h4').textContent = title;
|
||||||
|
li.querySelector('span').innerHTML = content
|
||||||
|
results.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightContent(content, hit) {
|
||||||
|
const amountLetters = 60
|
||||||
|
const { metadata } = hit.matchData
|
||||||
|
let from = 0
|
||||||
|
let to = 100
|
||||||
|
const keys = Object.keys(metadata).sort()
|
||||||
|
for (const key of keys) {
|
||||||
|
const positions = metadata[key]?.content?.position
|
||||||
|
if (!positions) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for (const position of positions) {
|
||||||
|
const positionStart = position[0]
|
||||||
|
from = Math.max(0, content.length - positionStart <= amountLetters
|
||||||
|
? positionStart - amountLetters * 2
|
||||||
|
: positionStart - amountLetters)
|
||||||
|
to = positionStart + position[1] + amountLetters
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let value = content.slice(from, to)
|
||||||
|
if (from !== 0) {
|
||||||
|
value = `...${value}`
|
||||||
|
}
|
||||||
|
for (const key of keys) {
|
||||||
|
value = value.replace(new RegExp(key, 'gi'), '<strong>$&</strong>')
|
||||||
|
}
|
||||||
|
|
||||||
|
return value + '...'
|
||||||
|
}
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
/**
|
/**
|
||||||
* @param {String} content
|
* @param {String} content
|
||||||
* @returns {Node}
|
* @returns {Node}
|
||||||
@ -101,4 +176,26 @@
|
|||||||
div.innerHTML = content;
|
div.innerHTML = content;
|
||||||
return div.firstChild;
|
return div.firstChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hide(element) {
|
||||||
|
element.classList.add('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(element) {
|
||||||
|
element.classList.remove('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSearchBox() {
|
||||||
|
if (!resultsContainer.classList.contains('hidden')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resultsContainer.scrollTop = 0
|
||||||
|
show(searchOverlay)
|
||||||
|
show(resultsContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideSearchBox() {
|
||||||
|
hide(searchOverlay)
|
||||||
|
hide(resultsContainer)
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
{{- if default true .Site.Params.BookSearch -}}
|
{{- if default true .Site.Params.BookSearch -}}
|
||||||
{{- $searchJSFile := printf "%s.search.js" .Language.Lang }}
|
{{- $searchJSFile := printf "%s.search.js" .Language.Lang }}
|
||||||
{{- $searchJS := resources.Get "search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | resources.Fingerprint }}
|
{{- $searchJS := resources.Get "search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | resources.Fingerprint }}
|
||||||
<script defer src="{{ "flexsearch.min.js" | relURL }}"></script>
|
<script defer src="{{ "lunr.min.js" | relURL }}"></script>
|
||||||
<script defer src="{{ $searchJS.RelPermalink }}" {{ template "integrity" $searchJS }}></script>
|
<script defer src="{{ $searchJS.RelPermalink }}" {{ template "integrity" $searchJS }}></script>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
{{ if default true .Site.Params.BookSearch }}
|
{{ if default true .Site.Params.BookSearch }}
|
||||||
<div class="book-search">
|
<div class="book-search">
|
||||||
<input type="text" id="book-search-input" placeholder="{{ i18n "Search" }}" aria-label="{{ i18n "Search" }}" maxlength="64" data-hotkeys="s/" />
|
<div id="search-overlay" class="hidden"></div>
|
||||||
|
<div id="book-search-input">
|
||||||
|
<img src="{{ "svg/search.svg" | relURL }}" class="book-icon" alt="Search" />
|
||||||
|
<input type="text" placeholder="{{ i18n "Search" }}" aria-label="{{ i18n "Search" }}" maxlength="64" data-hotkeys="s/" />
|
||||||
|
</div>
|
||||||
<div class="book-search-spinner hidden"></div>
|
<div class="book-search-spinner hidden"></div>
|
||||||
<ul id="book-search-results"></ul>
|
<div id="book-search-results">
|
||||||
|
<div id="book-search-hits" class="hidden" tabindex="0">
|
||||||
|
<ul id="book-search-list"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
42
static/flexsearch.min.js
vendored
42
static/flexsearch.min.js
vendored
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
FlexSearch v0.6.30
|
|
||||||
Copyright 2019 Nextapps GmbH
|
|
||||||
Author: Thomas Wilkerling
|
|
||||||
Released under the Apache 2.0 Licence
|
|
||||||
https://github.com/nextapps-de/flexsearch
|
|
||||||
*/
|
|
||||||
'use strict';(function(K,R,w){let L;(L=w.define)&&L.amd?L([],function(){return R}):(L=w.modules)?L[K.toLowerCase()]=R:"object"===typeof exports?module.exports=R:w[K]=R})("FlexSearch",function ma(K){function w(a,c){const b=c?c.id:a&&a.id;this.id=b||0===b?b:na++;this.init(a,c);fa(this,"index",function(){return this.a?Object.keys(this.a.index[this.a.keys[0]].c):Object.keys(this.c)});fa(this,"length",function(){return this.index.length})}function L(a,c,b,d){this.u!==this.g&&(this.o=this.o.concat(b),this.u++,
|
|
||||||
d&&this.o.length>=d&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(c,this.o),this.F&&this.F(this.o)));return this}function S(a){const c=B();for(const b in a)if(a.hasOwnProperty(b)){const d=a[b];F(d)?c[b]=d.slice(0):G(d)?c[b]=S(d):c[b]=d}return c}function W(a,c){const b=a.length,d=O(c),e=[];for(let f=0,h=0;f<b;f++){const g=a[f];if(d&&c(g)||!d&&!c[g])e[h++]=g}return e}function P(a,c,b,d,e,f,h,g,k,l){b=ha(b,h?0:e,g,f,c,k,l);let p;g&&(g=b.page,p=b.next,b=b.result);if(h)c=this.where(h,null,
|
|
||||||
e,b);else{c=b;b=this.l;e=c.length;f=Array(e);for(h=0;h<e;h++)f[h]=b[c[h]];c=f}b=c;d&&(O(d)||(M=d.split(":"),1<M.length?d=oa:(M=M[0],d=pa)),b.sort(d));b=T(g,p,b);this.cache&&this.j.set(a,b);return b}function fa(a,c,b){Object.defineProperty(a,c,{get:b})}function r(a){return new RegExp(a,"g")}function Q(a,c){for(let b=0;b<c.length;b+=2)a=a.replace(c[b],c[b+1]);return a}function V(a,c,b,d,e,f,h,g){if(c[b])return c[b];e=e?(g-(h||g/1.5))*f+(h||g/1.5)*e:f;c[b]=e;e>=h&&(a=a[g-(e+.5>>0)],a=a[b]||(a[b]=[]),
|
|
||||||
a[a.length]=d);return e}function ba(a,c){if(a){const b=Object.keys(a);for(let d=0,e=b.length;d<e;d++){const f=b[d],h=a[f];if(h)for(let g=0,k=h.length;g<k;g++)if(h[g]===c){1===k?delete a[f]:h.splice(g,1);break}else G(h[g])&&ba(h[g],c)}}}function ca(a){let c="",b="";var d="";for(let e=0;e<a.length;e++){const f=a[e];if(f!==b)if(e&&"h"===f){if(d="a"===d||"e"===d||"i"===d||"o"===d||"u"===d||"y"===d,("a"===b||"e"===b||"i"===b||"o"===b||"u"===b||"y"===b)&&d||" "===b)c+=f}else c+=f;d=e===a.length-1?"":a[e+
|
|
||||||
1];b=f}return c}function qa(a,c){a=a.length-c.length;return 0>a?1:a?-1:0}function pa(a,c){a=a[M];c=c[M];return a<c?-1:a>c?1:0}function oa(a,c){const b=M.length;for(let d=0;d<b;d++)a=a[M[d]],c=c[M[d]];return a<c?-1:a>c?1:0}function T(a,c,b){return a?{page:a,next:c?""+c:null,result:b}:b}function ha(a,c,b,d,e,f,h){let g,k=[];if(!0===b){b="0";var l=""}else l=b&&b.split(":");const p=a.length;if(1<p){const y=B(),t=[];let v,x;var n=0,m;let I;var u=!0;let D,E=0,N,da,X,ea;l&&(2===l.length?(X=l,l=!1):l=ea=
|
|
||||||
parseInt(l[0],10));if(h){for(v=B();n<p;n++)if("not"===e[n])for(x=a[n],I=x.length,m=0;m<I;m++)v["@"+x[m]]=1;else da=n+1;if(C(da))return T(b,g,k);n=0}else N=J(e)&&e;let Y;for(;n<p;n++){const ra=n===(da||p)-1;if(!N||!n)if((m=N||e&&e[n])&&"and"!==m)if("or"===m)Y=!1;else continue;else Y=f=!0;x=a[n];if(I=x.length){if(u)if(D){var q=D.length;for(m=0;m<q;m++){u=D[m];var A="@"+u;h&&v[A]||(y[A]=1,f||(k[E++]=u))}D=null;u=!1}else{D=x;continue}A=!1;for(m=0;m<I;m++){q=x[m];var z="@"+q;const Z=f?y[z]||0:n;if(!(!Z&&
|
|
||||||
!d||h&&v[z]||!f&&y[z]))if(Z===n){if(ra){if(!ea||--ea<E)if(k[E++]=q,c&&E===c)return T(b,E+(l||0),k)}else y[z]=n+1;A=!0}else d&&(z=t[Z]||(t[Z]=[]),z[z.length]=q)}if(Y&&!A&&!d)break}else if(Y&&!d)return T(b,g,x)}if(D)if(n=D.length,h)for(m=l?parseInt(l,10):0;m<n;m++)a=D[m],v["@"+a]||(k[E++]=a);else k=D;if(d)for(E=k.length,X?(n=parseInt(X[0],10)+1,m=parseInt(X[1],10)+1):(n=t.length,m=0);n--;)if(q=t[n]){for(I=q.length;m<I;m++)if(d=q[m],!h||!v["@"+d])if(k[E++]=d,c&&E===c)return T(b,n+":"+m,k);m=0}}else!p||
|
|
||||||
e&&"not"===e[0]||(k=a[0],l&&(l=parseInt(l[0],10)));c&&(h=k.length,l&&l>h&&(l=0),l=l||0,g=l+c,g<h?k=k.slice(l,g):(g=0,l&&(k=k.slice(l))));return T(b,g,k)}function J(a){return"string"===typeof a}function F(a){return a.constructor===Array}function O(a){return"function"===typeof a}function G(a){return"object"===typeof a}function C(a){return"undefined"===typeof a}function ia(a){const c=Array(a);for(let b=0;b<a;b++)c[b]=B();return c}function B(){return Object.create(null)}function sa(){let a,c;self.onmessage=
|
|
||||||
function(b){if(b=b.data)if(b.search){const d=c.search(b.content,b.threshold?{limit:b.limit,threshold:b.threshold,where:b.where}:b.limit);self.postMessage({id:a,content:b.content,limit:b.limit,result:d})}else b.add?c.add(b.id,b.content):b.update?c.update(b.id,b.content):b.remove?c.remove(b.id):b.clear?c.clear():b.info?(b=c.info(),b.worker=a,console.log(b)):b.register&&(a=b.id,b.options.cache=!1,b.options.async=!1,b.options.worker=!1,c=(new Function(b.register.substring(b.register.indexOf("{")+1,b.register.lastIndexOf("}"))))(),
|
|
||||||
c=new c(b.options))}}function ta(a,c,b,d){a=K("flexsearch","id"+a,sa,function(f){(f=f.data)&&f.result&&d(f.id,f.content,f.result,f.limit,f.where,f.cursor,f.suggest)},c);const e=ma.toString();b.id=c;a.postMessage({register:e,options:b,id:c});return a}const H={encode:"icase",f:"forward",split:/\W+/,cache:!1,async:!1,g:!1,D:!1,a:!1,b:9,threshold:0,depth:0},ja={memory:{encode:"extra",f:"strict",threshold:0,b:1},speed:{encode:"icase",f:"strict",threshold:1,b:3,depth:2},match:{encode:"extra",f:"full",threshold:1,
|
|
||||||
b:3},score:{encode:"extra",f:"strict",threshold:1,b:9,depth:4},balance:{encode:"balance",f:"strict",threshold:0,b:3,depth:3},fast:{encode:"icase",f:"strict",threshold:8,b:9,depth:1}},aa=[];let na=0;const ka={},la={};w.create=function(a,c){return new w(a,c)};w.registerMatcher=function(a){for(const c in a)a.hasOwnProperty(c)&&aa.push(r(c),a[c]);return this};w.registerEncoder=function(a,c){U[a]=c.bind(U);return this};w.registerLanguage=function(a,c){ka[a]=c.filter;la[a]=c.stemmer;return this};w.encode=
|
|
||||||
function(a,c){return U[a](c)};w.prototype.init=function(a,c){this.v=[];if(c){var b=c.preset;a=c}else a||(a=H),b=a.preset;c={};J(a)?(c=ja[a],a={}):b&&(c=ja[b]);if(b=a.worker)if("undefined"===typeof Worker)a.worker=!1,this.m=null;else{var d=parseInt(b,10)||4;this.C=-1;this.u=0;this.o=[];this.F=null;this.m=Array(d);for(var e=0;e<d;e++)this.m[e]=ta(this.id,e,a,L.bind(this))}this.f=a.tokenize||c.f||this.f||H.f;this.split=C(b=a.split)?this.split||H.split:J(b)?r(b):b;this.D=a.rtl||this.D||H.D;this.async=
|
|
||||||
"undefined"===typeof Promise||C(b=a.async)?this.async||H.async:b;this.g=C(b=a.worker)?this.g||H.g:b;this.threshold=C(b=a.threshold)?c.threshold||this.threshold||H.threshold:b;this.b=C(b=a.resolution)?b=c.b||this.b||H.b:b;b<=this.threshold&&(this.b=this.threshold+1);this.depth="strict"!==this.f||C(b=a.depth)?c.depth||this.depth||H.depth:b;this.w=(b=C(b=a.encode)?c.encode||H.encode:b)&&U[b]&&U[b].bind(U)||(O(b)?b:this.w||!1);(b=a.matcher)&&this.addMatcher(b);if(b=(c=a.lang)||a.filter){J(b)&&(b=ka[b]);
|
|
||||||
if(F(b)){d=this.w;e=B();for(var f=0;f<b.length;f++){var h=d?d(b[f]):b[f];e[h]=1}b=e}this.filter=b}if(b=c||a.stemmer){var g;c=J(b)?la[b]:b;d=this.w;e=[];for(g in c)c.hasOwnProperty(g)&&(f=d?d(g):g,e.push(r(f+"($|\\W)"),d?d(c[g]):c[g]));this.stemmer=g=e}this.a=e=(b=a.doc)?S(b):this.a||H.a;this.i=ia(this.b-(this.threshold||0));this.h=B();this.c=B();if(e){this.l=B();a.doc=null;g=e.index={};c=e.keys=[];d=e.field;f=e.tag;h=e.store;F(e.id)||(e.id=e.id.split(":"));if(h){var k=B();if(J(h))k[h]=1;else if(F(h))for(let l=
|
|
||||||
0;l<h.length;l++)k[h[l]]=1;else G(h)&&(k=h);e.store=k}if(f){this.G=B();h=B();if(d)if(J(d))h[d]=a;else if(F(d))for(k=0;k<d.length;k++)h[d[k]]=a;else G(d)&&(h=d);F(f)||(e.tag=f=[f]);for(d=0;d<f.length;d++)this.G[f[d]]=B();this.I=f;d=h}if(d){let l;F(d)||(G(d)?(l=d,e.field=d=Object.keys(d)):e.field=d=[d]);for(e=0;e<d.length;e++)f=d[e],F(f)||(l&&(a=l[f]),c[e]=f,d[e]=f.split(":")),g[f]=new w(a)}a.doc=b}this.B=!0;this.j=(this.cache=b=C(b=a.cache)?this.cache||H.cache:b)?new ua(b):!1;return this};w.prototype.encode=
|
|
||||||
function(a){a&&(aa.length&&(a=Q(a,aa)),this.v.length&&(a=Q(a,this.v)),this.w&&(a=this.w(a)),this.stemmer&&(a=Q(a,this.stemmer)));return a};w.prototype.addMatcher=function(a){const c=this.v;for(const b in a)a.hasOwnProperty(b)&&c.push(r(b),a[b]);return this};w.prototype.add=function(a,c,b,d,e){if(this.a&&G(a))return this.A("add",a,c);if(c&&J(c)&&(a||0===a)){var f="@"+a;if(this.c[f]&&!d)return this.update(a,c);if(this.g)return++this.C>=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:a,
|
|
||||||
content:c}),this.c[f]=""+this.C,b&&b(),this;if(!e){if(this.async&&"function"!==typeof importScripts){let t=this;f=new Promise(function(v){setTimeout(function(){t.add(a,c,null,d,!0);t=null;v()})});if(b)f.then(b);else return f;return this}if(b)return this.add(a,c,null,d,!0),b(),this}c=this.encode(c);if(!c.length)return this;b=this.f;e=O(b)?b(c):c.split(this.split);this.filter&&(e=W(e,this.filter));const n=B();n._ctx=B();const m=e.length,u=this.threshold,q=this.depth,A=this.b,z=this.i,y=this.D;for(let t=
|
|
||||||
0;t<m;t++){var h=e[t];if(h){var g=h.length,k=(y?t+1:m-t)/m,l="";switch(b){case "reverse":case "both":for(var p=g;--p;)l=h[p]+l,V(z,n,l,a,y?1:(g-p)/g,k,u,A-1);l="";case "forward":for(p=0;p<g;p++)l+=h[p],V(z,n,l,a,y?(p+1)/g:1,k,u,A-1);break;case "full":for(p=0;p<g;p++){const v=(y?p+1:g-p)/g;for(let x=g;x>p;x--)l=h.substring(p,x),V(z,n,l,a,v,k,u,A-1)}break;default:if(g=V(z,n,h,a,1,k,u,A-1),q&&1<m&&g>=u)for(g=n._ctx[h]||(n._ctx[h]=B()),h=this.h[h]||(this.h[h]=ia(A-(u||0))),k=t-q,l=t+q+1,0>k&&(k=0),l>
|
|
||||||
m&&(l=m);k<l;k++)k!==t&&V(h,g,e[k],a,0,A-(k<t?t-k:k-t),u,A-1)}}}this.c[f]=1;this.B=!1}return this};w.prototype.A=function(a,c,b){if(F(c)){var d=c.length;if(d--){for(var e=0;e<d;e++)this.A(a,c[e]);return this.A(a,c[d],b)}}else{var f=this.a.index,h=this.a.keys,g=this.a.tag;e=this.a.store;var k;var l=this.a.id;d=c;for(var p=0;p<l.length;p++)d=d[l[p]];if("remove"===a&&(delete this.l[d],l=h.length,l--)){for(c=0;c<l;c++)f[h[c]].remove(d);return f[h[l]].remove(d,b)}if(g){for(k=0;k<g.length;k++){var n=g[k];
|
|
||||||
var m=c;l=n.split(":");for(p=0;p<l.length;p++)m=m[l[p]];m="@"+m}k=this.G[n];k=k[m]||(k[m]=[])}l=this.a.field;for(let u=0,q=l.length;u<q;u++){n=l[u];g=c;for(m=0;m<n.length;m++)g=g[n[m]];n=f[h[u]];m="add"===a?n.add:n.update;u===q-1?m.call(n,d,g,b):m.call(n,d,g)}if(e){b=Object.keys(e);a=B();for(f=0;f<b.length;f++)if(h=b[f],e[h]){h=h.split(":");let u,q;for(l=0;l<h.length;l++)g=h[l],u=(u||c)[g],q=(q||a)[g]=u}c=a}k&&(k[k.length]=c);this.l[d]=c}return this};w.prototype.update=function(a,c,b){if(this.a&&
|
|
||||||
G(a))return this.A("update",a,c);this.c["@"+a]&&J(c)&&(this.remove(a),this.add(a,c,b,!0));return this};w.prototype.remove=function(a,c,b){if(this.a&&G(a))return this.A("remove",a,c);var d="@"+a;if(this.c[d]){if(this.g)return this.m[this.c[d]].postMessage({remove:!0,id:a}),delete this.c[d],c&&c(),this;if(!b){if(this.async&&"function"!==typeof importScripts){let e=this;d=new Promise(function(f){setTimeout(function(){e.remove(a,null,!0);e=null;f()})});if(c)d.then(c);else return d;return this}if(c)return this.remove(a,
|
|
||||||
null,!0),c(),this}for(c=0;c<this.b-(this.threshold||0);c++)ba(this.i[c],a);this.depth&&ba(this.h,a);delete this.c[d];this.B=!1}return this};let M;w.prototype.search=function(a,c,b,d){if(G(c)){if(F(c))for(var e=0;e<c.length;e++)c[e].query=a;else c.query=a;a=c;c=1E3}else c&&O(c)?(b=c,c=1E3):c||0===c||(c=1E3);if(this.g){this.F=b;this.u=0;this.o=[];for(var f=0;f<this.g;f++)this.m[f].postMessage({search:!0,limit:c,content:a})}else{var h=[],g=a;if(G(a)&&!F(a)){b||(b=a.callback)&&(g.callback=null);var k=
|
|
||||||
a.sort;var l=a.page;c=a.limit;f=a.threshold;var p=a.suggest;a=a.query}if(this.a){f=this.a.index;const y=g.where;var n=g.bool||"or",m=g.field;let t=n;let v,x;if(m)F(m)||(m=[m]);else if(F(g)){var u=g;m=[];t=[];for(var q=0;q<g.length;q++)d=g[q],e=d.bool||n,m[q]=d.field,t[q]=e,"not"===e?v=!0:"and"===e&&(x=!0)}else m=this.a.keys;n=m.length;for(q=0;q<n;q++)u&&(g=u[q]),l&&!J(g)&&(g.page=null,g.limit=0),h[q]=f[m[q]].search(g,0);if(b)return b(P.call(this,a,t,h,k,c,p,y,l,x,v));if(this.async){const I=this;return new Promise(function(D){Promise.all(h).then(function(E){D(P.call(I,
|
|
||||||
a,t,E,k,c,p,y,l,x,v))})})}return P.call(this,a,t,h,k,c,p,y,l,x,v)}f||(f=this.threshold||0);if(!d){if(this.async&&"function"!==typeof importScripts){let y=this;f=new Promise(function(t){setTimeout(function(){t(y.search(g,c,null,!0));y=null})});if(b)f.then(b);else return f;return this}if(b)return b(this.search(g,c,null,!0)),this}if(!a||!J(a))return h;g=a;if(this.cache)if(this.B){if(b=this.j.get(a))return b}else this.j.clear(),this.B=!0;g=this.encode(g);if(!g.length)return h;b=this.f;b=O(b)?b(g):g.split(this.split);
|
|
||||||
this.filter&&(b=W(b,this.filter));u=b.length;d=!0;e=[];var A=B(),z=0;1<u&&(this.depth&&"strict"===this.f?n=!0:b.sort(qa));if(!n||(q=this.h)){const y=this.b;for(;z<u;z++){let t=b[z];if(t){if(n){if(!m)if(q[t])m=t,A[t]=1;else if(!p)return h;if(p&&z===u-1&&!e.length)n=!1,t=m||t,A[t]=0;else if(!m)continue}if(!A[t]){const v=[];let x=!1,I=0;const D=n?q[m]:this.i;if(D){let E;for(let N=0;N<y-f;N++)if(E=D[N]&&D[N][t])v[I++]=E,x=!0}if(x)m=t,e[e.length]=1<I?v.concat.apply([],v):v[0];else if(!p){d=!1;break}A[t]=
|
|
||||||
1}}}}else d=!1;d&&(h=ha(e,c,l,p));this.cache&&this.j.set(a,h);return h}};w.prototype.find=function(a,c){return this.where(a,c,1)[0]||null};w.prototype.where=function(a,c,b,d){const e=this.l,f=[];let h=0;let g;var k;let l;if(G(a)){b||(b=c);var p=Object.keys(a);var n=p.length;g=!1;if(1===n&&"id"===p[0])return[e[a.id]];if((k=this.I)&&!d)for(var m=0;m<k.length;m++){var u=k[m],q=a[u];if(!C(q)){l=this.G[u]["@"+q];if(0===--n)return l;p.splice(p.indexOf(u),1);delete a[u];break}}k=Array(n);for(m=0;m<n;m++)k[m]=
|
|
||||||
p[m].split(":")}else{if(O(a)){c=d||Object.keys(e);b=c.length;for(p=0;p<b;p++)n=e[c[p]],a(n)&&(f[h++]=n);return f}if(C(c))return[e[a]];if("id"===a)return[e[c]];p=[a];n=1;k=[a.split(":")];g=!0}d=l||d||Object.keys(e);m=d.length;for(u=0;u<m;u++){q=l?d[u]:e[d[u]];let A=!0;for(let z=0;z<n;z++){g||(c=a[p[z]]);const y=k[z],t=y.length;let v=q;if(1<t)for(let x=0;x<t;x++)v=v[y[x]];else v=v[y[0]];if(v!==c){A=!1;break}}if(A&&(f[h++]=q,b&&h===b))break}return f};w.prototype.info=function(){if(this.g)for(let a=0;a<
|
|
||||||
this.g;a++)this.m[a].postMessage({info:!0,id:this.id});else return{id:this.id,items:this.length,cache:this.cache&&this.cache.s?this.cache.s.length:!1,matcher:aa.length+(this.v?this.v.length:0),worker:this.g,threshold:this.threshold,depth:this.depth,resolution:this.b,contextual:this.depth&&"strict"===this.f}};w.prototype.clear=function(){return this.destroy().init()};w.prototype.destroy=function(){this.cache&&(this.j.clear(),this.j=null);this.i=this.h=this.c=null;if(this.a){const a=this.a.keys;for(let c=
|
|
||||||
0;c<a.length;c++)this.a.index[a[c]].destroy();this.a=this.l=null}return this};w.prototype.export=function(a){const c=!a||C(a.serialize)||a.serialize;if(this.a){const d=!a||C(a.doc)||a.doc;var b=!a||C(a.index)||a.index;a=[];let e=0;if(b)for(b=this.a.keys;e<b.length;e++){const f=this.a.index[b[e]];a[e]=[f.i,f.h,Object.keys(f.c)]}d&&(a[e]=this.l)}else a=[this.i,this.h,Object.keys(this.c)];c&&(a=JSON.stringify(a));return a};w.prototype.import=function(a,c){if(!c||C(c.serialize)||c.serialize)a=JSON.parse(a);
|
|
||||||
const b=B();if(this.a){var d=!c||C(c.doc)||c.doc,e=0;if(!c||C(c.index)||c.index){c=this.a.keys;const h=c.length;for(var f=a[0][2];e<f.length;e++)b[f[e]]=1;for(e=0;e<h;e++){f=this.a.index[c[e]];const g=a[e];g&&(f.i=g[0],f.h=g[1],f.c=b)}}d&&(this.l=G(d)?d:a[e])}else{d=a[2];for(e=0;e<d.length;e++)b[d[e]]=1;this.i=a[0];this.h=a[1];this.c=b}};const va=function(){const a=r("\\s+"),c=r("[^a-z0-9 ]"),b=[r("[-/]")," ",c,"",a," "];return function(d){return ca(Q(d.toLowerCase(),b))}}(),U={icase:function(a){return a.toLowerCase()},
|
|
||||||
simple:function(){const a=r("\\s+"),c=r("[^a-z0-9 ]"),b=r("[-/]"),d=r("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),e=r("[\u00e8\u00e9\u00ea\u00eb]"),f=r("[\u00ec\u00ed\u00ee\u00ef]"),h=r("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),g=r("[\u00f9\u00fa\u00fb\u00fc\u0171]"),k=r("[\u00fd\u0177\u00ff]"),l=r("\u00f1"),p=r("[\u00e7c]"),n=r("\u00df"),m=r(" & "),u=[d,"a",e,"e",f,"i",h,"o",g,"u",k,"y",l,"n",p,"k",n,"s",m," and ",b," ",c,"",a," "];return function(q){q=Q(q.toLowerCase(),u);return" "===q?"":q}}(),advanced:function(){const a=
|
|
||||||
r("ae"),c=r("ai"),b=r("ay"),d=r("ey"),e=r("oe"),f=r("ue"),h=r("ie"),g=r("sz"),k=r("zs"),l=r("ck"),p=r("cc"),n=r("sh"),m=r("th"),u=r("dt"),q=r("ph"),A=r("pf"),z=r("ou"),y=r("uo"),t=[a,"a",c,"ei",b,"ei",d,"ei",e,"o",f,"u",h,"i",g,"s",k,"s",n,"s",l,"k",p,"k",m,"t",u,"t",q,"f",A,"f",z,"o",y,"u"];return function(v,x){if(!v)return v;v=this.simple(v);2<v.length&&(v=Q(v,t));x||1<v.length&&(v=ca(v));return v}}(),extra:function(){const a=r("p"),c=r("z"),b=r("[cgq]"),d=r("n"),e=r("d"),f=r("[vw]"),h=r("[aeiouy]"),
|
|
||||||
g=[a,"b",c,"s",b,"k",d,"m",e,"t",f,"f",h,""];return function(k){if(!k)return k;k=this.advanced(k,!0);if(1<k.length){k=k.split(" ");for(let l=0;l<k.length;l++){const p=k[l];1<p.length&&(k[l]=p[0]+Q(p.substring(1),g))}k=k.join(" ");k=ca(k)}return k}}(),balance:va},ua=function(){function a(c){this.clear();this.H=!0!==c&&c}a.prototype.clear=function(){this.cache=B();this.count=B();this.index=B();this.s=[]};a.prototype.set=function(c,b){if(this.H&&C(this.cache[c])){let d=this.s.length;if(d===this.H){d--;
|
|
||||||
const e=this.s[d];delete this.cache[e];delete this.count[e];delete this.index[e]}this.index[c]=d;this.s[d]=c;this.count[c]=-1;this.cache[c]=b;this.get(c)}else this.cache[c]=b};a.prototype.get=function(c){const b=this.cache[c];if(this.H&&b){var d=++this.count[c];const f=this.index;let h=f[c];if(0<h){const g=this.s;for(var e=h;this.count[g[--h]]<=d&&-1!==h;);h++;if(h!==e){for(d=e;d>h;d--)e=g[d-1],g[d]=e,f[e]=d;g[h]=c;f[c]=h}}}return b};return a}();return w}(function(){const K={},R="undefined"!==typeof Blob&&
|
|
||||||
"undefined"!==typeof URL&&URL.createObjectURL;return function(w,L,S,W,P){S=R?URL.createObjectURL(new Blob(["("+S.toString()+")()"],{type:"text/javascript"})):w+".min.js";w+="-"+L;K[w]||(K[w]=[]);K[w][P]=new Worker(S);K[w][P].onmessage=W;return K[w][P]}}()),this);
|
|
6
static/lunr.min.js
vendored
Normal file
6
static/lunr.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
static/svg/search.svg
Normal file
6
static/svg/search.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M0 0H24V24H0z" transform="matrix(0 1 1 0 -5 -5)"/>
|
||||||
|
<path fill="#736E7D" fill-rule="nonzero" d="M18.657 17.003l-3.041-3.042c-.016-.016-.035-.027-.052-.042.598-.908.948-1.995.948-3.163C16.512 7.577 13.935 5 10.756 5 7.577 5 5 7.577 5 10.756c0 3.179 2.577 5.756 5.756 5.756 1.168 0 2.255-.35 3.163-.948.015.017.026.036.042.052l3.042 3.041c.457.457 1.197.457 1.654 0 .457-.457.457-1.197 0-1.654zm-7.901-2.487c-2.077 0-3.76-1.683-3.76-3.76s1.683-3.76 3.76-3.76 3.76 1.683 3.76 3.76-1.683 3.76-3.76 3.76z" transform="matrix(0 1 1 0 -5 -5)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 701 B |
Loading…
Reference in New Issue
Block a user