diff --git a/.vs/alphazero-official.github.io/v16/.suo b/.vs/alphazero-official.github.io/v16/.suo
index eca9849..9906aae 100644
Binary files a/.vs/alphazero-official.github.io/v16/.suo and b/.vs/alphazero-official.github.io/v16/.suo differ
diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite
index 40bccf7..2e9285e 100644
Binary files a/.vs/slnx.sqlite and b/.vs/slnx.sqlite differ
diff --git a/assets/js/sjs.js b/assets/js/sjs.js
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/fuzzysearch/.editorconfig b/node_modules/fuzzysearch/.editorconfig
new file mode 100644
index 0000000..5d12634
--- /dev/null
+++ b/node_modules/fuzzysearch/.editorconfig
@@ -0,0 +1,13 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/node_modules/fuzzysearch/.jshintignore b/node_modules/fuzzysearch/.jshintignore
new file mode 100644
index 0000000..f06235c
--- /dev/null
+++ b/node_modules/fuzzysearch/.jshintignore
@@ -0,0 +1,2 @@
+node_modules
+dist
diff --git a/node_modules/fuzzysearch/.jshintrc b/node_modules/fuzzysearch/.jshintrc
new file mode 100644
index 0000000..63bccb7
--- /dev/null
+++ b/node_modules/fuzzysearch/.jshintrc
@@ -0,0 +1,21 @@
+{
+ "curly": true,
+ "eqeqeq": true,
+ "newcap": true,
+ "noarg": true,
+ "noempty": true,
+ "nonew": true,
+ "sub": true,
+ "validthis": true,
+ "undef": true,
+ "trailing": true,
+ "boss": true,
+ "eqnull": true,
+ "strict": true,
+ "immed": true,
+ "expr": true,
+ "latedef": "nofunc",
+ "quotmark": "single",
+ "indent": 2,
+ "node": true
+}
diff --git a/node_modules/fuzzysearch/.npmignore b/node_modules/fuzzysearch/.npmignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/node_modules/fuzzysearch/.npmignore
@@ -0,0 +1 @@
+node_modules
diff --git a/node_modules/fuzzysearch/CHANGELOG.md b/node_modules/fuzzysearch/CHANGELOG.md
new file mode 100644
index 0000000..711183d
--- /dev/null
+++ b/node_modules/fuzzysearch/CHANGELOG.md
@@ -0,0 +1,18 @@
+# v1.0.3 Short Fuse
+
+- Improved circuit-breaker when `needle` and `haystack` length are equal
+
+# v1.0.2 Vodka Tonic
+
+- Slightly updated circuit-breaker that tests for equal length first
+- Doubled method performance ([see jsperf tests](http://jsperf.com/fuzzysearch-regex/3))
+
+# v1.0.1 Circuit Breaker
+
+- Introduced a circuit-breaker where queries longer than the searched string will return `false`
+- Introduced a circuit-breaker where queries identical to the searched string will return `true`
+- Introduced a circuit-breaker where text containing the entire query will return `true`
+
+# v1.0.0 IPO
+
+- Initial Public Release
diff --git a/node_modules/fuzzysearch/LICENSE b/node_modules/fuzzysearch/LICENSE
new file mode 100644
index 0000000..b980cef
--- /dev/null
+++ b/node_modules/fuzzysearch/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright © 2015 Nicolas Bevacqua
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/fuzzysearch/README.md b/node_modules/fuzzysearch/README.md
new file mode 100644
index 0000000..15b38aa
--- /dev/null
+++ b/node_modules/fuzzysearch/README.md
@@ -0,0 +1,45 @@
+# fuzzysearch
+
+> Tiny and blazing-fast fuzzy search in JavaScript
+
+Fuzzy searching allows for flexibly matching a string with partial input, useful for filtering data very quickly based on lightweight user input.
+
+# Demo
+
+To see `fuzzysearch` in action, head over to [bevacqua.github.io/horsey][3], which is a demo of an autocomplete component that uses `fuzzysearch` to filter out results based on user input.
+
+# Install
+
+From `npm`
+
+```shell
+npm install --save fuzzysearch
+```
+
+# `fuzzysearch(needle, haystack)`
+
+Returns `true` if `needle` matches `haystack` using a fuzzy-searching algorithm. Note that this program doesn't implement _[levenshtein distance][2]_, but rather a simplified version where **there's no approximation**. The method will return `true` only if each character in the `needle` can be found in the `haystack` and occurs after the preceding character.
+
+```js
+fuzzysearch('twl', 'cartwheel') // <- true
+fuzzysearch('cart', 'cartwheel') // <- true
+fuzzysearch('cw', 'cartwheel') // <- true
+fuzzysearch('ee', 'cartwheel') // <- true
+fuzzysearch('art', 'cartwheel') // <- true
+fuzzysearch('eeel', 'cartwheel') // <- false
+fuzzysearch('dog', 'cartwheel') // <- false
+```
+
+An exciting application for this kind of algorithm is to filter options from an autocomplete menu, check out [horsey][3] for an example on how that might look like.
+
+# But! _`RegExp`s...!_
+
+![chart showing abysmal performance for regexp-based implementation][1]
+
+# License
+
+MIT
+
+[1]: https://cloud.githubusercontent.com/assets/934293/6495796/106a61a6-c2ac-11e4-945d-3d1bb066a76e.png
+[2]: http://en.wikipedia.org/wiki/Levenshtein_distance
+[3]: http://bevacqua.github.io/horsey
diff --git a/node_modules/fuzzysearch/index.js b/node_modules/fuzzysearch/index.js
new file mode 100644
index 0000000..047762f
--- /dev/null
+++ b/node_modules/fuzzysearch/index.js
@@ -0,0 +1,24 @@
+'use strict';
+
+function fuzzysearch (needle, haystack) {
+ var tlen = haystack.length;
+ var qlen = needle.length;
+ if (qlen > tlen) {
+ return false;
+ }
+ if (qlen === tlen) {
+ return needle === haystack;
+ }
+ outer: for (var i = 0, j = 0; i < qlen; i++) {
+ var nch = needle.charCodeAt(i);
+ while (j < tlen) {
+ if (haystack.charCodeAt(j++) === nch) {
+ continue outer;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+module.exports = fuzzysearch;
diff --git a/node_modules/fuzzysearch/package.json b/node_modules/fuzzysearch/package.json
new file mode 100644
index 0000000..690aba7
--- /dev/null
+++ b/node_modules/fuzzysearch/package.json
@@ -0,0 +1,51 @@
+{
+ "_from": "fuzzysearch@^1.0.3",
+ "_id": "fuzzysearch@1.0.3",
+ "_inBundle": false,
+ "_integrity": "sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==",
+ "_location": "/fuzzysearch",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "fuzzysearch@^1.0.3",
+ "name": "fuzzysearch",
+ "escapedName": "fuzzysearch",
+ "rawSpec": "^1.0.3",
+ "saveSpec": null,
+ "fetchSpec": "^1.0.3"
+ },
+ "_requiredBy": [
+ "/simple-jekyll-search"
+ ],
+ "_resolved": "https://registry.npmjs.org/fuzzysearch/-/fuzzysearch-1.0.3.tgz",
+ "_shasum": "dffc80f6d6b04223f2226aa79dd194231096d008",
+ "_spec": "fuzzysearch@^1.0.3",
+ "_where": "C:\\alphazero-official.github.io\\node_modules\\simple-jekyll-search",
+ "author": {
+ "name": "Nicolas Bevacqua",
+ "email": "ng@bevacqua.io",
+ "url": "http://bevacqua.io"
+ },
+ "bugs": {
+ "url": "https://github.com/bevacqua/fuzzysearch/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Tiny and blazing-fast fuzzy search in JavaScript",
+ "devDependencies": {
+ "jshint": "^2.6.0",
+ "tape": "^3.5.0"
+ },
+ "homepage": "https://github.com/bevacqua/fuzzysearch",
+ "license": "MIT",
+ "name": "fuzzysearch",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/bevacqua/fuzzysearch.git"
+ },
+ "scripts": {
+ "test": "jshint . && tape test/*.js"
+ },
+ "version": "1.0.3"
+}
diff --git a/node_modules/fuzzysearch/test/fuzzysearch.js b/node_modules/fuzzysearch/test/fuzzysearch.js
new file mode 100644
index 0000000..b178185
--- /dev/null
+++ b/node_modules/fuzzysearch/test/fuzzysearch.js
@@ -0,0 +1,14 @@
+'use strict';
+
+var test = require('tape');
+var fuzzysearch = require('..');
+
+test('fuzzysearch should match expectations', function (t) {
+ t.equal(fuzzysearch('car', 'cartwheel'), true);
+ t.equal(fuzzysearch('cwhl', 'cartwheel'), true);
+ t.equal(fuzzysearch('cwheel', 'cartwheel'), true);
+ t.equal(fuzzysearch('cartwheel', 'cartwheel'), true);
+ t.equal(fuzzysearch('cwheeel', 'cartwheel'), false);
+ t.equal(fuzzysearch('lw', 'cartwheel'), false);
+ t.end();
+});
diff --git a/node_modules/simple-jekyll-search/LICENSE.md b/node_modules/simple-jekyll-search/LICENSE.md
new file mode 100644
index 0000000..7ea5087
--- /dev/null
+++ b/node_modules/simple-jekyll-search/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Christian Fei
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/node_modules/simple-jekyll-search/README.md b/node_modules/simple-jekyll-search/README.md
new file mode 100644
index 0000000..c5925d7
--- /dev/null
+++ b/node_modules/simple-jekyll-search/README.md
@@ -0,0 +1,334 @@
+# [Simple-Jekyll-Search](https://www.npmjs.com/package/simple-jekyll-search)
+
+[](https://travis-ci.org/christian-fei/Simple-Jekyll-Search)
+[](https://david-dm.org/christian-fei/Simple-Jekyll-Search)
+[](https://david-dm.org/christian-fei/Simple-Jekyll-Search?type=dev)
+
+A JavaScript library to add search functionality to any Jekyll blog.
+
+## Use case
+
+You have a blog, built with Jekyll, and want a **lightweight search functionality** on your blog, purely client-side?
+
+*No server configurations or databases to maintain*.
+
+Just **5 minutes** to have a **fully working searchable blog**.
+
+---
+
+## Installation
+
+### npm
+
+```sh
+npm install simple-jekyll-search
+```
+
+## Getting started
+
+### Create `search.json`
+
+Place the following code in a file called `search.json` in the **root** of your Jekyll blog. (You can also get a copy [from here](/example/search.json))
+
+This file will be used as a small data source to perform the searches on the client side:
+
+```yaml
+---
+layout: none
+---
+[
+ {% for post in site.posts %}
+ {
+ "title" : "{{ post.title | escape }}",
+ "category" : "{{ post.category }}",
+ "tags" : "{{ post.tags | join: ', ' }}",
+ "url" : "{{ site.baseurl }}{{ post.url }}",
+ "date" : "{{ post.date }}"
+ } {% unless forloop.last %},{% endunless %}
+ {% endfor %}
+]
+```
+
+
+## Preparing the plugin
+
+### Add DOM elements
+
+SimpleJekyllSearch needs two `DOM` elements to work:
+
+- a search input field
+- a result container to display the results
+
+#### Give me the code
+
+Here is the code you can use with the default configuration:
+
+You need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)
+
+For example in **_layouts/default.html**:
+
+```html
+
+
+
+
+
+
+```
+
+
+## Usage
+
+Customize SimpleJekyllSearch by passing in your configuration options:
+
+```js
+var sjs = SimpleJekyllSearch({
+ searchInput: document.getElementById('search-input'),
+ resultsContainer: document.getElementById('results-container'),
+ json: '/search.json'
+})
+```
+
+### returns { search }
+
+A new instance of SimpleJekyllSearch returns an object, with the only property `search`.
+
+`search` is a function used to simulate a user input and display the matching results.
+
+E.g.:
+
+```js
+var sjs = SimpleJekyllSearch({ ...options })
+sjs.search('Hello')
+```
+
+💡 it can be used to filter posts by tags or categories!
+
+## Options
+
+Here is a list of the available options, usage questions, troubleshooting & guides.
+
+### searchInput (Element) [required]
+
+The input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.
+
+
+### resultsContainer (Element) [required]
+
+The container element in which the search results should be rendered in. Typically a ``.
+
+
+### json (String|JSON) [required]
+
+You can either pass in an URL to the `search.json` file, or the results in form of JSON directly, to save one round trip to get the data.
+
+
+### searchResultTemplate (String) [optional]
+
+The template of a single rendered search result.
+
+The templating syntax is very simple: You just enclose the properties you want to replace with curly braces.
+
+E.g.
+
+The template
+
+```js
+var sjs = SimpleJekyllSearch({
+ searchInput: document.getElementById('search-input'),
+ resultsContainer: document.getElementById('results-container'),
+ json: '/search.json',
+ searchResultTemplate: '{title} '
+})
+```
+
+will render to the following
+
+```html
+Welcome to Jekyll!
+```
+
+If the `search.json` contains this data
+
+```json
+[
+ {
+ "title" : "Welcome to Jekyll!",
+ "category" : "",
+ "tags" : "",
+ "url" : "/jekyll/update/2014/11/01/welcome-to-jekyll.html",
+ "date" : "2014-11-01 21:07:22 +0100"
+ }
+]
+```
+
+
+### templateMiddleware (Function) [optional]
+
+A function that will be called whenever a match in the template is found.
+
+It gets passed the current property name, property value, and the template.
+
+If the function returns a non-undefined value, it gets replaced in the template.
+
+This can be potentially useful for manipulating URLs etc.
+
+Example:
+
+```js
+SimpleJekyllSearch({
+ ...
+ templateMiddleware: function(prop, value, template) {
+ if (prop === 'bar') {
+ return value.replace(/^\//, '')
+ }
+ }
+ ...
+})
+```
+
+See the [tests](https://github.com/christian-fei/Simple-Jekyll-Search/blob/master/tests/Templater.test.js) for an in-depth code example
+
+### sortMiddleware (Function) [optional]
+
+A function that will be used to sort the filtered results.
+
+It can be used for example to group the sections together.
+
+Example:
+
+```js
+SimpleJekyllSearch({
+ ...
+ sortMiddleware: function(a, b) {
+ var astr = String(a.section) + "-" + String(a.caption);
+ var bstr = String(b.section) + "-" + String(b.caption);
+ return astr.localeCompare(bstr)
+ }
+ ...
+})
+```
+
+### noResultsText (String) [optional]
+
+The HTML that will be shown if the query didn't match anything.
+
+
+### limit (Number) [optional]
+
+You can limit the number of posts rendered on the page.
+
+
+### fuzzy (Boolean) [optional]
+
+Enable fuzzy search to allow less restrictive matching.
+
+### exclude (Array) [optional]
+
+Pass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).
+
+### success (Function) [optional]
+
+A function called once the data has been loaded.
+
+### debounceTime (Number) [optional]
+
+Limit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no `debounceTime` (milliseconds) is provided a search will be triggered on each keystroke.
+
+---
+
+## If search isn't working due to invalid JSON
+
+- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use `remove_chars` as a filter.
+
+For example: in search.json, replace
+
+```json
+"content": "{{ page.content | strip_html | strip_newlines }}"
+```
+
+with
+
+```json
+"content": "{{ page.content | strip_html | strip_newlines | remove_chars | escape }}"
+```
+
+If this doesn't work when using Github pages you can try `jsonify` to make sure the content is json compatible:
+
+```js
+"content": {{ page.content | jsonify }}
+```
+
+**Note: you don't need to use quotes `"` in this since `jsonify` automatically inserts them.**
+
+
+## Enabling full-text search
+
+Replace `search.json` with the following code:
+
+```yaml
+---
+layout: none
+---
+[
+ {% for post in site.posts %}
+ {
+ "title" : "{{ post.title | escape }}",
+ "category" : "{{ post.category }}",
+ "tags" : "{{ post.tags | join: ', ' }}",
+ "url" : "{{ site.baseurl }}{{ post.url }}",
+ "date" : "{{ post.date }}",
+ "content" : "{{ post.content | strip_html | strip_newlines }}"
+ } {% unless forloop.last %},{% endunless %}
+ {% endfor %}
+ ,
+ {% for page in site.pages %}
+ {
+ {% if page.title != nil %}
+ "title" : "{{ page.title | escape }}",
+ "category" : "{{ page.category }}",
+ "tags" : "{{ page.tags | join: ', ' }}",
+ "url" : "{{ site.baseurl }}{{ page.url }}",
+ "date" : "{{ page.date }}",
+ "content" : "{{ page.content | strip_html | strip_newlines }}"
+ {% endif %}
+ } {% unless forloop.last %},{% endunless %}
+ {% endfor %}
+]
+```
+
+
+
+## Development
+
+- `npm install`
+- `npm test`
+
+#### Acceptance tests
+
+```bash
+cd example; jekyll serve
+
+# in another tab
+
+npm run cypress -- run
+```
+
+## Contributors
+
+Thanks to all [contributors](https://github.com/christian-fei/Simple-Jekyll-Search/graphs/contributors) over the years! You are the best :)
+
+> [@daviddarnes](https://github.com/daviddarnes)
+[@XhmikosR](https://github.com/XhmikosR)
+[@PeterDaveHello](https://github.com/PeterDaveHello)
+[@mikeybeck](https://github.com/mikeybeck)
+[@egladman](https://github.com/egladman)
+[@midzer](https://github.com/midzer)
+[@eduardoboucas](https://github.com/eduardoboucas)
+[@kremalicious](https://github.com/kremalicious)
+[@tibotiber](https://github.com/tibotiber)
+and many others!
+
+## Stargazers over time
+
+[](https://starchart.cc/christian-fei/Simple-Jekyll-Search)
diff --git a/node_modules/simple-jekyll-search/dest/simple-jekyll-search.js b/node_modules/simple-jekyll-search/dest/simple-jekyll-search.js
new file mode 100644
index 0000000..3afbb60
--- /dev/null
+++ b/node_modules/simple-jekyll-search/dest/simple-jekyll-search.js
@@ -0,0 +1,433 @@
+/*!
+ * Simple-Jekyll-Search
+ * Copyright 2015-2020, Christian Fei
+ * Licensed under the MIT License.
+ */
+
+(function(){
+'use strict'
+
+var _$Templater_7 = {
+ compile: compile,
+ setOptions: setOptions
+}
+
+const options = {}
+options.pattern = /\{(.*?)\}/g
+options.template = ''
+options.middleware = function () {}
+
+function setOptions (_options) {
+ options.pattern = _options.pattern || options.pattern
+ options.template = _options.template || options.template
+ if (typeof _options.middleware === 'function') {
+ options.middleware = _options.middleware
+ }
+}
+
+function compile (data) {
+ return options.template.replace(options.pattern, function (match, prop) {
+ const value = options.middleware(prop, data[prop], options.template)
+ if (typeof value !== 'undefined') {
+ return value
+ }
+ return data[prop] || match
+ })
+}
+
+'use strict';
+
+function fuzzysearch (needle, haystack) {
+ var tlen = haystack.length;
+ var qlen = needle.length;
+ if (qlen > tlen) {
+ return false;
+ }
+ if (qlen === tlen) {
+ return needle === haystack;
+ }
+ outer: for (var i = 0, j = 0; i < qlen; i++) {
+ var nch = needle.charCodeAt(i);
+ while (j < tlen) {
+ if (haystack.charCodeAt(j++) === nch) {
+ continue outer;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+var _$fuzzysearch_1 = fuzzysearch;
+
+'use strict'
+
+/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
+
+var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
+
+function FuzzySearchStrategy () {
+ this.matches = function (string, crit) {
+ return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
+ }
+}
+
+'use strict'
+
+var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
+
+function LiteralSearchStrategy () {
+ this.matches = function (str, crit) {
+ if (!str) return false
+
+ str = str.trim().toLowerCase()
+ crit = crit.trim().toLowerCase()
+
+ return crit.split(' ').filter(function (word) {
+ return str.indexOf(word) >= 0
+ }).length === crit.split(' ').length
+ }
+}
+
+'use strict'
+
+var _$Repository_4 = {
+ put: put,
+ clear: clear,
+ search: search,
+ setOptions: __setOptions_4
+}
+
+/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
+/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
+
+function NoSort () {
+ return 0
+}
+
+const data = []
+let opt = {}
+
+opt.fuzzy = false
+opt.limit = 10
+opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
+opt.sort = NoSort
+opt.exclude = []
+
+function put (data) {
+ if (isObject(data)) {
+ return addObject(data)
+ }
+ if (isArray(data)) {
+ return addArray(data)
+ }
+ return undefined
+}
+function clear () {
+ data.length = 0
+ return data
+}
+
+function isObject (obj) {
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+function isArray (obj) {
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
+}
+
+function addObject (_data) {
+ data.push(_data)
+ return data
+}
+
+function addArray (_data) {
+ const added = []
+ clear()
+ for (let i = 0, len = _data.length; i < len; i++) {
+ if (isObject(_data[i])) {
+ added.push(addObject(_data[i]))
+ }
+ }
+ return added
+}
+
+function search (crit) {
+ if (!crit) {
+ return []
+ }
+ return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
+}
+
+function __setOptions_4 (_opt) {
+ opt = _opt || {}
+
+ opt.fuzzy = _opt.fuzzy || false
+ opt.limit = _opt.limit || 10
+ opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
+ opt.sort = _opt.sort || NoSort
+ opt.exclude = _opt.exclude || []
+}
+
+function findMatches (data, crit, strategy, opt) {
+ const matches = []
+ for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
+ const match = findMatchesInObject(data[i], crit, strategy, opt)
+ if (match) {
+ matches.push(match)
+ }
+ }
+ return matches
+}
+
+function findMatchesInObject (obj, crit, strategy, opt) {
+ for (const key in obj) {
+ if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
+ return obj
+ }
+ }
+}
+
+function isExcluded (term, excludedTerms) {
+ for (let i = 0, len = excludedTerms.length; i < len; i++) {
+ const excludedTerm = excludedTerms[i]
+ if (new RegExp(excludedTerm).test(term)) {
+ return true
+ }
+ }
+ return false
+}
+
+/* globals ActiveXObject:false */
+
+'use strict'
+
+var _$JSONLoader_2 = {
+ load: load
+}
+
+function load (location, callback) {
+ const xhr = getXHR()
+ xhr.open('GET', location, true)
+ xhr.onreadystatechange = createStateChangeListener(xhr, callback)
+ xhr.send()
+}
+
+function createStateChangeListener (xhr, callback) {
+ return function () {
+ if (xhr.readyState === 4 && xhr.status === 200) {
+ try {
+ callback(null, JSON.parse(xhr.responseText))
+ } catch (err) {
+ callback(err, null)
+ }
+ }
+ }
+}
+
+function getXHR () {
+ return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
+}
+
+'use strict'
+
+var _$OptionsValidator_3 = function OptionsValidator (params) {
+ if (!validateParams(params)) {
+ throw new Error('-- OptionsValidator: required options missing')
+ }
+
+ if (!(this instanceof OptionsValidator)) {
+ return new OptionsValidator(params)
+ }
+
+ const requiredOptions = params.required
+
+ this.getRequiredOptions = function () {
+ return requiredOptions
+ }
+
+ this.validate = function (parameters) {
+ const errors = []
+ requiredOptions.forEach(function (requiredOptionName) {
+ if (typeof parameters[requiredOptionName] === 'undefined') {
+ errors.push(requiredOptionName)
+ }
+ })
+ return errors
+ }
+
+ function validateParams (params) {
+ if (!params) {
+ return false
+ }
+ return typeof params.required !== 'undefined' && params.required instanceof Array
+ }
+}
+
+'use strict'
+
+var _$utils_9 = {
+ merge: merge,
+ isJSON: isJSON
+}
+
+function merge (defaultParams, mergeParams) {
+ const mergedOptions = {}
+ for (const option in defaultParams) {
+ mergedOptions[option] = defaultParams[option]
+ if (typeof mergeParams[option] !== 'undefined') {
+ mergedOptions[option] = mergeParams[option]
+ }
+ }
+ return mergedOptions
+}
+
+function isJSON (json) {
+ try {
+ if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
+ return true
+ }
+ return false
+ } catch (err) {
+ return false
+ }
+}
+
+var _$src_8 = {};
+(function (window) {
+ 'use strict'
+
+ let options = {
+ searchInput: null,
+ resultsContainer: null,
+ json: [],
+ success: Function.prototype,
+ searchResultTemplate: '{title} ',
+ templateMiddleware: Function.prototype,
+ sortMiddleware: function () {
+ return 0
+ },
+ noResultsText: 'No results found',
+ limit: 10,
+ fuzzy: false,
+ debounceTime: null,
+ exclude: []
+ }
+
+ let debounceTimerHandle
+ const debounce = function (func, delayMillis) {
+ if (delayMillis) {
+ clearTimeout(debounceTimerHandle)
+ debounceTimerHandle = setTimeout(func, delayMillis)
+ } else {
+ func.call()
+ }
+ }
+
+ const requiredOptions = ['searchInput', 'resultsContainer', 'json']
+
+ /* removed: const _$Templater_7 = require('./Templater') */;
+ /* removed: const _$Repository_4 = require('./Repository') */;
+ /* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
+ const optionsValidator = _$OptionsValidator_3({
+ required: requiredOptions
+ })
+ /* removed: const _$utils_9 = require('./utils') */;
+
+ window.SimpleJekyllSearch = function (_options) {
+ const errors = optionsValidator.validate(_options)
+ if (errors.length > 0) {
+ throwError('You must specify the following required options: ' + requiredOptions)
+ }
+
+ options = _$utils_9.merge(options, _options)
+
+ _$Templater_7.setOptions({
+ template: options.searchResultTemplate,
+ middleware: options.templateMiddleware
+ })
+
+ _$Repository_4.setOptions({
+ fuzzy: options.fuzzy,
+ limit: options.limit,
+ sort: options.sortMiddleware,
+ exclude: options.exclude
+ })
+
+ if (_$utils_9.isJSON(options.json)) {
+ initWithJSON(options.json)
+ } else {
+ initWithURL(options.json)
+ }
+
+ const rv = {
+ search: search
+ }
+
+ typeof options.success === 'function' && options.success.call(rv)
+ return rv
+ }
+
+ function initWithJSON (json) {
+ _$Repository_4.put(json)
+ registerInput()
+ }
+
+ function initWithURL (url) {
+ _$JSONLoader_2.load(url, function (err, json) {
+ if (err) {
+ throwError('failed to get JSON (' + url + ')')
+ }
+ initWithJSON(json)
+ })
+ }
+
+ function emptyResultsContainer () {
+ options.resultsContainer.innerHTML = ''
+ }
+
+ function appendToResultsContainer (text) {
+ options.resultsContainer.innerHTML += text
+ }
+
+ function registerInput () {
+ options.searchInput.addEventListener('input', function (e) {
+ if (isWhitelistedKey(e.which)) {
+ emptyResultsContainer()
+ debounce(function () { search(e.target.value) }, options.debounceTime)
+ }
+ })
+ }
+
+ function search (query) {
+ if (isValidQuery(query)) {
+ emptyResultsContainer()
+ render(_$Repository_4.search(query), query)
+ }
+ }
+
+ function render (results, query) {
+ const len = results.length
+ if (len === 0) {
+ return appendToResultsContainer(options.noResultsText)
+ }
+ for (let i = 0; i < len; i++) {
+ results[i].query = query
+ appendToResultsContainer(_$Templater_7.compile(results[i]))
+ }
+ }
+
+ function isValidQuery (query) {
+ return query && query.length > 0
+ }
+
+ function isWhitelistedKey (key) {
+ return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
+ }
+
+ function throwError (message) {
+ throw new Error('SimpleJekyllSearch --- ' + message)
+ }
+})(window)
+
+}());
diff --git a/node_modules/simple-jekyll-search/dest/simple-jekyll-search.min.js b/node_modules/simple-jekyll-search/dest/simple-jekyll-search.min.js
new file mode 100644
index 0000000..81df5d5
--- /dev/null
+++ b/node_modules/simple-jekyll-search/dest/simple-jekyll-search.min.js
@@ -0,0 +1,6 @@
+/*!
+ * Simple-Jekyll-Search
+ * Copyright 2015-2020, Christian Fei
+ * Licensed under the MIT License.
+ */
+!function(){"use strict";var f={compile:function(r){return i.template.replace(i.pattern,function(t,e){var n=i.middleware(e,r[e],i.template);return void 0!==n?n:r[e]||t})},setOptions:function(t){i.pattern=t.pattern||i.pattern,i.template=t.template||i.template,"function"==typeof t.middleware&&(i.middleware=t.middleware)}};const i={pattern:/\{(.*?)\}/g,template:"",middleware:function(){}};var n=function(t,e){var n=e.length,r=t.length;if(n{title} ',templateMiddleware:Function.prototype,sortMiddleware:function(){return 0},noResultsText:"No results found",limit:10,fuzzy:!1,debounceTime:null,exclude:[]},n;const e=function(t,e){e?(clearTimeout(n),n=setTimeout(t,e)):t.call()};var r=["searchInput","resultsContainer","json"];const o=m({required:r});function u(t){d.put(t),i.searchInput.addEventListener("input",function(t){-1===[13,16,20,37,38,39,40,91].indexOf(t.which)&&(c(),e(function(){l(t.target.value)},i.debounceTime))})}function c(){i.resultsContainer.innerHTML=""}function s(t){i.resultsContainer.innerHTML+=t}function l(t){var e;(e=t)&&0 dest/simple-jekyll-search.js",
+ "build": "npm run browserify && npm run uglify",
+ "copy-example-code": "cp dest/* example/js/",
+ "cypress": "cypress",
+ "dist": "npm run build && npm run copy-example-code",
+ "lint": "standard",
+ "postbuild": "npm run copy-example-code",
+ "prebuild": "npm run test",
+ "pretest": "npm run lint",
+ "start": "cd example; jekyll serve",
+ "test": "ava",
+ "uglify": "uglifyjs --compress --mangle --ie8 --comments \"/^/*!/\" --output dest/simple-jekyll-search.min.js dest/simple-jekyll-search.js"
+ },
+ "standard": {
+ "ignore": [
+ "cypress/**",
+ "example/**",
+ "dest/**"
+ ]
+ },
+ "version": "1.10.0"
+}
diff --git a/node_modules/simple-jekyll-search/src/JSONLoader.js b/node_modules/simple-jekyll-search/src/JSONLoader.js
new file mode 100644
index 0000000..fc4e9a4
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/JSONLoader.js
@@ -0,0 +1,30 @@
+/* globals ActiveXObject:false */
+
+'use strict'
+
+module.exports = {
+ load: load
+}
+
+function load (location, callback) {
+ const xhr = getXHR()
+ xhr.open('GET', location, true)
+ xhr.onreadystatechange = createStateChangeListener(xhr, callback)
+ xhr.send()
+}
+
+function createStateChangeListener (xhr, callback) {
+ return function () {
+ if (xhr.readyState === 4 && xhr.status === 200) {
+ try {
+ callback(null, JSON.parse(xhr.responseText))
+ } catch (err) {
+ callback(err, null)
+ }
+ }
+ }
+}
+
+function getXHR () {
+ return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
+}
diff --git a/node_modules/simple-jekyll-search/src/OptionsValidator.js b/node_modules/simple-jekyll-search/src/OptionsValidator.js
new file mode 100644
index 0000000..d29a668
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/OptionsValidator.js
@@ -0,0 +1,34 @@
+'use strict'
+
+module.exports = function OptionsValidator (params) {
+ if (!validateParams(params)) {
+ throw new Error('-- OptionsValidator: required options missing')
+ }
+
+ if (!(this instanceof OptionsValidator)) {
+ return new OptionsValidator(params)
+ }
+
+ const requiredOptions = params.required
+
+ this.getRequiredOptions = function () {
+ return requiredOptions
+ }
+
+ this.validate = function (parameters) {
+ const errors = []
+ requiredOptions.forEach(function (requiredOptionName) {
+ if (typeof parameters[requiredOptionName] === 'undefined') {
+ errors.push(requiredOptionName)
+ }
+ })
+ return errors
+ }
+
+ function validateParams (params) {
+ if (!params) {
+ return false
+ }
+ return typeof params.required !== 'undefined' && params.required instanceof Array
+ }
+}
diff --git a/node_modules/simple-jekyll-search/src/Repository.js b/node_modules/simple-jekyll-search/src/Repository.js
new file mode 100644
index 0000000..8a02a2d
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/Repository.js
@@ -0,0 +1,108 @@
+'use strict'
+
+module.exports = {
+ put: put,
+ clear: clear,
+ search: search,
+ setOptions: setOptions
+}
+
+const FuzzySearchStrategy = require('./SearchStrategies/FuzzySearchStrategy')
+const LiteralSearchStrategy = require('./SearchStrategies/LiteralSearchStrategy')
+
+function NoSort () {
+ return 0
+}
+
+const data = []
+let opt = {}
+
+opt.fuzzy = false
+opt.limit = 10
+opt.searchStrategy = opt.fuzzy ? FuzzySearchStrategy : LiteralSearchStrategy
+opt.sort = NoSort
+opt.exclude = []
+
+function put (data) {
+ if (isObject(data)) {
+ return addObject(data)
+ }
+ if (isArray(data)) {
+ return addArray(data)
+ }
+ return undefined
+}
+function clear () {
+ data.length = 0
+ return data
+}
+
+function isObject (obj) {
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+function isArray (obj) {
+ return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
+}
+
+function addObject (_data) {
+ data.push(_data)
+ return data
+}
+
+function addArray (_data) {
+ const added = []
+ clear()
+ for (let i = 0, len = _data.length; i < len; i++) {
+ if (isObject(_data[i])) {
+ added.push(addObject(_data[i]))
+ }
+ }
+ return added
+}
+
+function search (crit) {
+ if (!crit) {
+ return []
+ }
+ return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
+}
+
+function setOptions (_opt) {
+ opt = _opt || {}
+
+ opt.fuzzy = _opt.fuzzy || false
+ opt.limit = _opt.limit || 10
+ opt.searchStrategy = _opt.fuzzy ? FuzzySearchStrategy : LiteralSearchStrategy
+ opt.sort = _opt.sort || NoSort
+ opt.exclude = _opt.exclude || []
+}
+
+function findMatches (data, crit, strategy, opt) {
+ const matches = []
+ for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
+ const match = findMatchesInObject(data[i], crit, strategy, opt)
+ if (match) {
+ matches.push(match)
+ }
+ }
+ return matches
+}
+
+function findMatchesInObject (obj, crit, strategy, opt) {
+ for (const key in obj) {
+ if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
+ return obj
+ }
+ }
+}
+
+function isExcluded (term, excludedTerms) {
+ for (let i = 0, len = excludedTerms.length; i < len; i++) {
+ const excludedTerm = excludedTerms[i]
+ if (new RegExp(excludedTerm).test(term)) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/node_modules/simple-jekyll-search/src/SearchStrategies/FuzzySearchStrategy.js b/node_modules/simple-jekyll-search/src/SearchStrategies/FuzzySearchStrategy.js
new file mode 100644
index 0000000..6a9e55c
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/SearchStrategies/FuzzySearchStrategy.js
@@ -0,0 +1,14 @@
+'use strict'
+
+const fuzzysearch = require('fuzzysearch')
+
+module.exports = new FuzzySearchStrategy()
+
+function FuzzySearchStrategy () {
+ this.matches = function (string, crit) {
+ if (string === null) {
+ return false
+ }
+ return fuzzysearch(crit.toLowerCase(), string.toLowerCase())
+ }
+}
diff --git a/node_modules/simple-jekyll-search/src/SearchStrategies/LiteralSearchStrategy.js b/node_modules/simple-jekyll-search/src/SearchStrategies/LiteralSearchStrategy.js
new file mode 100644
index 0000000..0ca0762
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/SearchStrategies/LiteralSearchStrategy.js
@@ -0,0 +1,13 @@
+'use strict'
+
+module.exports = new LiteralSearchStrategy()
+
+function LiteralSearchStrategy () {
+ this.matches = function (str, crit) {
+ if (!str) return false
+ str = str.trim().toLowerCase()
+ crit = crit.endsWith(' ') ? [crit.toLowerCase()] : crit.trim().toLowerCase().split(' ')
+
+ return crit.filter(word => str.indexOf(word) >= 0).length === crit.length
+ }
+}
diff --git a/node_modules/simple-jekyll-search/src/Templater.js b/node_modules/simple-jekyll-search/src/Templater.js
new file mode 100644
index 0000000..f89ea22
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/Templater.js
@@ -0,0 +1,29 @@
+'use strict'
+
+module.exports = {
+ compile: compile,
+ setOptions: setOptions
+}
+
+const options = {}
+options.pattern = /\{(.*?)\}/g
+options.template = ''
+options.middleware = function () {}
+
+function setOptions (_options) {
+ options.pattern = _options.pattern || options.pattern
+ options.template = _options.template || options.template
+ if (typeof _options.middleware === 'function') {
+ options.middleware = _options.middleware
+ }
+}
+
+function compile (data) {
+ return options.template.replace(options.pattern, function (match, prop) {
+ const value = options.middleware(prop, data[prop], options.template)
+ if (typeof value !== 'undefined') {
+ return value
+ }
+ return data[prop] || match
+ })
+}
diff --git a/node_modules/simple-jekyll-search/src/index.js b/node_modules/simple-jekyll-search/src/index.js
new file mode 100644
index 0000000..8f9317f
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/index.js
@@ -0,0 +1,138 @@
+(function (window) {
+ 'use strict'
+
+ let options = {
+ searchInput: null,
+ resultsContainer: null,
+ json: [],
+ success: Function.prototype,
+ searchResultTemplate: '{title} ',
+ templateMiddleware: Function.prototype,
+ sortMiddleware: function () {
+ return 0
+ },
+ noResultsText: 'No results found',
+ limit: 10,
+ fuzzy: false,
+ debounceTime: null,
+ exclude: [],
+ onSearch: Function.prototype
+ }
+
+ let debounceTimerHandle
+ const debounce = function (func, delayMillis) {
+ if (delayMillis) {
+ clearTimeout(debounceTimerHandle)
+ debounceTimerHandle = setTimeout(func, delayMillis)
+ } else {
+ func.call()
+ }
+ }
+
+ const requiredOptions = ['searchInput', 'resultsContainer', 'json']
+
+ const templater = require('./Templater')
+ const repository = require('./Repository')
+ const jsonLoader = require('./JSONLoader')
+ const optionsValidator = require('./OptionsValidator')({
+ required: requiredOptions
+ })
+ const utils = require('./utils')
+
+ window.SimpleJekyllSearch = function (_options) {
+ const errors = optionsValidator.validate(_options)
+ if (errors.length > 0) {
+ throwError('You must specify the following required options: ' + requiredOptions)
+ }
+
+ options = utils.merge(options, _options)
+
+ templater.setOptions({
+ template: options.searchResultTemplate,
+ middleware: options.templateMiddleware
+ })
+
+ repository.setOptions({
+ fuzzy: options.fuzzy,
+ limit: options.limit,
+ sort: options.sortMiddleware,
+ exclude: options.exclude
+ })
+
+ if (utils.isJSON(options.json)) {
+ initWithJSON(options.json)
+ } else {
+ initWithURL(options.json)
+ }
+
+ const rv = {
+ search: search
+ }
+
+ typeof options.success === 'function' && options.success.call(rv)
+ return rv
+ }
+
+ function initWithJSON (json) {
+ repository.put(json)
+ registerInput()
+ }
+
+ function initWithURL (url) {
+ jsonLoader.load(url, function (err, json) {
+ if (err) {
+ throwError('failed to get JSON (' + url + ')')
+ }
+ initWithJSON(json)
+ })
+ }
+
+ function emptyResultsContainer () {
+ options.resultsContainer.innerHTML = ''
+ }
+
+ function appendToResultsContainer (text) {
+ options.resultsContainer.innerHTML += text
+ }
+
+ function registerInput () {
+ options.searchInput.addEventListener('input', function (e) {
+ if (isWhitelistedKey(e.which)) {
+ emptyResultsContainer()
+ debounce(function () { search(e.target.value) }, options.debounceTime)
+ }
+ })
+ }
+
+ function search (query) {
+ if (isValidQuery(query)) {
+ emptyResultsContainer()
+ render(repository.search(query), query)
+
+ typeof options.onSearch === 'function' && options.onSearch.call()
+ }
+ }
+
+ function render (results, query) {
+ const len = results.length
+ if (len === 0) {
+ return appendToResultsContainer(options.noResultsText)
+ }
+ for (let i = 0; i < len; i++) {
+ results[i].query = query
+ appendToResultsContainer(templater.compile(results[i]))
+ }
+ }
+
+ function isValidQuery (query) {
+ return query && query.length > 0
+ }
+
+ function isWhitelistedKey (key) {
+ return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
+ }
+
+ function throwError (message) {
+ throw new Error('SimpleJekyllSearch --- ' + message)
+ }
+})(window)
diff --git a/node_modules/simple-jekyll-search/src/utils.js b/node_modules/simple-jekyll-search/src/utils.js
new file mode 100644
index 0000000..2ff6011
--- /dev/null
+++ b/node_modules/simple-jekyll-search/src/utils.js
@@ -0,0 +1,28 @@
+'use strict'
+
+module.exports = {
+ merge: merge,
+ isJSON: isJSON
+}
+
+function merge (defaultParams, mergeParams) {
+ const mergedOptions = {}
+ for (const option in defaultParams) {
+ mergedOptions[option] = defaultParams[option]
+ if (typeof mergeParams[option] !== 'undefined') {
+ mergedOptions[option] = mergeParams[option]
+ }
+ }
+ return mergedOptions
+}
+
+function isJSON (json) {
+ try {
+ if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
+ return true
+ }
+ return false
+ } catch (err) {
+ return false
+ }
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..673ef7d
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,19 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "fuzzysearch": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fuzzysearch/-/fuzzysearch-1.0.3.tgz",
+ "integrity": "sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg=="
+ },
+ "simple-jekyll-search": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/simple-jekyll-search/-/simple-jekyll-search-1.10.0.tgz",
+ "integrity": "sha512-4SdHfAjEe9mngvj4wt8A7OsF9Rl3+onHY1ruQC+bUnecbNbdvzVcAbL+UH5mE+v2CWgUb95dyZjHhyqUGSa2hA==",
+ "requires": {
+ "fuzzysearch": "^1.0.3"
+ }
+ }
+ }
+}
diff --git a/search.json b/search.json
new file mode 100644
index 0000000..a9a0c78
--- /dev/null
+++ b/search.json
@@ -0,0 +1,14 @@
+---
+layout: none
+---
+[
+ {% for post in site.posts %}
+ {
+ "title" : "{{ post.title | escape }}",
+ "category" : "{{ post.category }}",
+ "tags" : "{{ post.tags | join: ', ' }}",
+ "url" : "{{ site.baseurl }}{{ post.url }}",
+ "date" : "{{ post.date }}"
+ } {% unless forloop.last %},{% endunless %}
+ {% endfor %}
+]
\ No newline at end of file