aboutsummaryrefslogtreecommitdiff
path: root/public/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'public/javascripts')
-rw-r--r--public/javascripts/autocomplete.js121
-rw-r--r--public/javascripts/bundle.js415
-rw-r--r--public/javascripts/frontpage.js5
-rw-r--r--public/javascripts/iframe.js14
-rw-r--r--public/javascripts/main.js1
-rw-r--r--public/javascripts/search.js28
6 files changed, 568 insertions, 16 deletions
diff --git a/public/javascripts/autocomplete.js b/public/javascripts/autocomplete.js
index 7a56e16..7e7fcbe 100644
--- a/public/javascripts/autocomplete.js
+++ b/public/javascripts/autocomplete.js
@@ -1,15 +1,124 @@
-const autocomplete = {}
-const self = autocomplete
+/* global USERS */
+
+const fuzzy = require('fuzzy')
+const search = require('./search')
+
+const self = {}
+
+self._items = []
+self._selectedItemIndex = -1
self._nodes = {
+ form: document.querySelector('#search'),
input: document.querySelector('input[type="search"]'),
autocomplete: document.querySelector('.autocomplete')
}
-self._textUpdate = function () {
- self._nodes.autocomplete
+self.getSelectedItem = function () {
+ if (self.getItems() === []) return
+
+ if (self.getSelectedItemIndex() === -1) {
+ return self.getItems()[0]
+ } else {
+ return self.getItems()[self.getSelectedItemIndex()]
+ }
+}
+
+self.getSelectedItemIndex = function () {
+ return self._selectedItemIndex
+}
+
+self.getItems = function () {
+ return self._items
+}
+
+self._removeAllItems = function () {
+ while (self._nodes.autocomplete.firstChild) {
+ self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild)
+ }
+ self._items = []
+ self._selectedItemIndex = -1
+}
+
+self._addItem = function (item) {
+ const listItem = document.createElement('li')
+ listItem.textContent = item.value
+ listItem.addEventListener('click', self._handleItemClick)
+ self._nodes.autocomplete.appendChild(listItem)
+ self._items.push(item)
+}
+
+self._moveSelected = function (shift) {
+ if (self._selectedItemIndex + shift >= self.getItems().length) {
+ self._selectedItemIndex = -1
+ } else if (self._selectedItemIndex + shift < -1) {
+ self._selectedItemIndex = self.getItems().length - 1
+ } else {
+ self._selectedItemIndex += shift
+ }
+
+ for (let i = 0; i < self.getItems().length; i++) {
+ self._nodes.autocomplete.children[i].classList.remove('selected')
+ }
+ if (self._selectedItemIndex >= 0) {
+ self._nodes.autocomplete
+ .children[self._selectedItemIndex].classList.add('selected')
+ }
+}
+
+self._calculate = function (searchTerm) {
+ const allResults = fuzzy.filter(searchTerm, USERS, {
+ extract: item => item.value
+ })
+ const firstResults = allResults.slice(0, 7)
+
+ const originalResults = firstResults.map(result => result.original)
+
+ return originalResults
+}
+
+self._handleItemClick = function (event) {
+ const itemIndex = Array.prototype.indexOf
+ .call(self._nodes.autocomplete.children, event.target)
+ console.log(itemIndex)
+ self._selectedItemIndex = itemIndex
+ console.log(search)
+ search.submit()
+}
+
+self._handleFocus = function () {
+ self._nodes.autocomplete.style.display = 'block'
+}
+
+self._handleBlur = function (event) {
+ // console.log(document.querySelector(':focus'))
+ // if (event.target.parentNode === self._nodes.autocomplete) return
+ // self._nodes.autocomplete.style.display = 'none'
+}
+
+self._handleTextUpdate = function () {
+ const results = self._calculate(self._nodes.input.value)
+
+ self._removeAllItems()
+ for (let i = 0; i < results.length; i++) {
+ self._addItem(results[i])
+ }
+}
+
+self._handleKeydown = function (event) {
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
+ event.preventDefault()
+ if (event.key === 'ArrowDown') {
+ self._moveSelected(1)
+ } else if (event.key === 'ArrowUp') {
+ self._moveSelected(-1)
+ }
+ }
}
-self._nodes.input.addEventListener('input', self.hide)
+self._nodes.input.addEventListener('focus', self._handleFocus)
+self._nodes.input.addEventListener('blur', self._handleBlur)
+self._nodes.input.addEventListener('input', self._handleTextUpdate)
+self._nodes.input.addEventListener('keydown', self._handleKeydown)
-module.exports = autocomplete
+module.exports = self
diff --git a/public/javascripts/bundle.js b/public/javascripts/bundle.js
index 1f12e86..76516d9 100644
--- a/public/javascripts/bundle.js
+++ b/public/javascripts/bundle.js
@@ -1,9 +1,318 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-const frontpage = {};
-const self = frontpage;
+/*
+ * Fuzzy
+ * https://github.com/myork/fuzzy
+ *
+ * Copyright (c) 2012 Matt York
+ * Licensed under the MIT license.
+ */
+
+(function() {
+
+var root = this;
+
+var fuzzy = {};
+
+// Use in node or in browser
+if (typeof exports !== 'undefined') {
+ module.exports = fuzzy;
+} else {
+ root.fuzzy = fuzzy;
+}
+
+// Return all elements of `array` that have a fuzzy
+// match against `pattern`.
+fuzzy.simpleFilter = function(pattern, array) {
+ return array.filter(function(string) {
+ return fuzzy.test(pattern, string);
+ });
+};
+
+// Does `pattern` fuzzy match `string`?
+fuzzy.test = function(pattern, string) {
+ return fuzzy.match(pattern, string) !== null;
+};
+
+// If `pattern` matches `string`, wrap each matching character
+// in `opts.pre` and `opts.post`. If no match, return null
+fuzzy.match = function(pattern, string, opts) {
+ opts = opts || {};
+ var patternIdx = 0
+ , result = []
+ , len = string.length
+ , totalScore = 0
+ , currScore = 0
+ // prefix
+ , pre = opts.pre || ''
+ // suffix
+ , post = opts.post || ''
+ // String to compare against. This might be a lowercase version of the
+ // raw string
+ , compareString = opts.caseSensitive && string || string.toLowerCase()
+ , ch, compareChar;
+
+ pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
+
+ // For each character in the string, either add it to the result
+ // or wrap in template if it's the next string in the pattern
+ for(var idx = 0; idx < len; idx++) {
+ ch = string[idx];
+ if(compareString[idx] === pattern[patternIdx]) {
+ ch = pre + ch + post;
+ patternIdx += 1;
+
+ // consecutive characters should increase the score more than linearly
+ currScore += 1 + currScore;
+ } else {
+ currScore = 0;
+ }
+ totalScore += currScore;
+ result[result.length] = ch;
+ }
+
+ // return rendered string if we have a match for every char
+ if(patternIdx === pattern.length) {
+ return {rendered: result.join(''), score: totalScore};
+ }
+
+ return null;
+};
+
+// The normal entry point. Filters `arr` for matches against `pattern`.
+// It returns an array with matching values of the type:
+//
+// [{
+// string: '<b>lah' // The rendered string
+// , index: 2 // The index of the element in `arr`
+// , original: 'blah' // The original element in `arr`
+// }]
+//
+// `opts` is an optional argument bag. Details:
+//
+// opts = {
+// // string to put before a matching character
+// pre: '<b>'
+//
+// // string to put after matching character
+// , post: '</b>'
+//
+// // Optional function. Input is an entry in the given arr`,
+// // output should be the string to test `pattern` against.
+// // In this example, if `arr = [{crying: 'koala'}]` we would return
+// // 'koala'.
+// , extract: function(arg) { return arg.crying; }
+// }
+fuzzy.filter = function(pattern, arr, opts) {
+ opts = opts || {};
+ return arr
+ .reduce(function(prev, element, idx, arr) {
+ var str = element;
+ if(opts.extract) {
+ str = opts.extract(element);
+ }
+ var rendered = fuzzy.match(pattern, str, opts);
+ if(rendered != null) {
+ prev[prev.length] = {
+ string: rendered.rendered
+ , score: rendered.score
+ , index: idx
+ , original: element
+ };
+ }
+ return prev;
+ }, [])
+
+ // Sort by score. Browsers are inconsistent wrt stable/unstable
+ // sorting, so force stable by using the index in the case of tie.
+ // See http://ofb.net/~sethml/is-sort-stable.html
+ .sort(function(a,b) {
+ var compare = b.score - a.score;
+ if(compare) return compare;
+ return a.index - b.index;
+ });
+};
+
+
+}());
+
+
+},{}],2:[function(require,module,exports){
+'use strict';
+module.exports = leftPad;
+
+var cache = [
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' '
+];
+
+function leftPad (str, len, ch) {
+ // convert `str` to `string`
+ str = str + '';
+ // `len` is the `pad`'s length now
+ len = len - str.length;
+ // doesn't need to pad
+ if (len <= 0) return str;
+ // `ch` defaults to `' '`
+ if (!ch && ch !== 0) ch = ' ';
+ // convert `ch` to `string`
+ ch = ch + '';
+ // cache common use cases
+ if (ch === ' ' && len < 10) return cache[len] + str;
+ // `pad` starts with an empty string
+ var pad = '';
+ // loop
+ while (true) {
+ // add `ch` to `pad` if `len` is odd
+ if (len & 1) pad += ch;
+ // devide `len` by 2, ditch the fraction
+ len >>= 1;
+ // "double" the `ch` so this operation count grows logarithmically on `len`
+ // each time `ch` is "doubled", the `len` would need to be "doubled" too
+ // similar to finding a value in binary search tree, hence O(log(n))
+ if (len) ch += ch;
+ // `len` is 0, exit the loop
+ else break;
+ }
+ // pad `str`!
+ return pad + str;
+}
+
+},{}],3:[function(require,module,exports){
+/* global USERS */
+
+const fuzzy = require('fuzzy');
+const search = require('./search');
+
+const self = {};
+
+self._items = [];
+self._selectedItemIndex = -1;
+
+self._nodes = {
+ form: document.querySelector('#search'),
+ input: document.querySelector('input[type="search"]'),
+ autocomplete: document.querySelector('.autocomplete')
+};
+
+self.getSelectedItem = function () {
+ if (self.getItems() === []) return;
+
+ if (self.getSelectedItemIndex() === -1) {
+ return self.getItems()[0];
+ } else {
+ return self.getItems()[self.getSelectedItemIndex()];
+ }
+};
+
+self.getSelectedItemIndex = function () {
+ return self._selectedItemIndex;
+};
+
+self.getItems = function () {
+ return self._items;
+};
+
+self._removeAllItems = function () {
+ while (self._nodes.autocomplete.firstChild) {
+ self._nodes.autocomplete.removeChild(self._nodes.autocomplete.firstChild);
+ }
+ self._items = [];
+ self._selectedItemIndex = -1;
+};
+
+self._addItem = function (item) {
+ const listItem = document.createElement('li');
+ listItem.textContent = item.value;
+ listItem.addEventListener('click', self._handleItemClick);
+ self._nodes.autocomplete.appendChild(listItem);
+ self._items.push(item);
+};
+
+self._moveSelected = function (shift) {
+ if (self._selectedItemIndex + shift >= self.getItems().length) {
+ self._selectedItemIndex = -1;
+ } else if (self._selectedItemIndex + shift < -1) {
+ self._selectedItemIndex = self.getItems().length - 1;
+ } else {
+ self._selectedItemIndex += shift;
+ }
+
+ for (let i = 0; i < self.getItems().length; i++) {
+ self._nodes.autocomplete.children[i].classList.remove('selected');
+ }
+ if (self._selectedItemIndex >= 0) {
+ self._nodes.autocomplete.children[self._selectedItemIndex].classList.add('selected');
+ }
+};
+
+self._calculate = function (searchTerm) {
+ const allResults = fuzzy.filter(searchTerm, USERS, {
+ extract: item => item.value
+ });
+ const firstResults = allResults.slice(0, 7);
+
+ const originalResults = firstResults.map(result => result.original);
+
+ return originalResults;
+};
+
+self._handleItemClick = function (event) {
+ const itemIndex = Array.prototype.indexOf.call(self._nodes.autocomplete.children, event.target);
+ console.log(itemIndex);
+ self._selectedItemIndex = itemIndex;
+ console.log(search);
+ search.submit();
+};
+
+self._handleFocus = function () {
+ self._nodes.autocomplete.style.display = 'block';
+};
+
+self._handleBlur = function (event) {
+ // console.log(document.querySelector(':focus'))
+ // if (event.target.parentNode === self._nodes.autocomplete) return
+ // self._nodes.autocomplete.style.display = 'none'
+};
+
+self._handleTextUpdate = function () {
+ const results = self._calculate(self._nodes.input.value);
+
+ self._removeAllItems();
+ for (let i = 0; i < results.length; i++) {
+ self._addItem(results[i]);
+ }
+};
+
+self._handleKeydown = function (event) {
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
+ event.preventDefault();
+ if (event.key === 'ArrowDown') {
+ self._moveSelected(1);
+ } else if (event.key === 'ArrowUp') {
+ self._moveSelected(-1);
+ }
+ }
+};
+
+self._nodes.input.addEventListener('focus', self._handleFocus);
+self._nodes.input.addEventListener('blur', self._handleBlur);
+self._nodes.input.addEventListener('input', self._handleTextUpdate);
+self._nodes.input.addEventListener('keydown', self._handleKeydown);
+
+module.exports = self;
+
+},{"./search":9,"fuzzy":1}],4:[function(require,module,exports){
+const self = {};
self._nodes = {
- search: document.querySelector('#search'),
input: document.querySelector('input[type="search"]')
};
@@ -21,14 +330,106 @@ self.hide = function () {
self._nodes.input.addEventListener('input', self.hide);
-module.exports = frontpage;
+module.exports = self;
-},{}],2:[function(require,module,exports){
+},{}],5:[function(require,module,exports){
+var leftPad = require('left-pad');
+var getWeek = require('./getWeek');
+
+function getURLOfUsers(weekOffset, type, id) {
+ return `//${ window.location.host }/meetingpointProxy/Roosters-AL%2Fdoc%2Fdagroosters%2F` + `${ getWeek() + weekOffset }%2F${ type }%2F${ type }${ leftPad(id, 5, '0') }.htm`;
+}
+
+module.exports = getURLOfUsers;
+
+},{"./getWeek":6,"left-pad":2}],6:[function(require,module,exports){
+// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js,
+// were using the same code as they do to be sure that we always get the same
+// week number.
+function getWeek() {
+ // Create a copy of this date object
+ const target = new Date();
+
+ // ISO week date weeks start on monday
+ // so correct the day number
+ const dayNr = (target.getDay() + 6) % 7;
+
+ // ISO 8601 states that week 1 is the week
+ // with the first thursday of that year.
+ // Set the target date to the thursday in the target week
+ target.setDate(target.getDate() - dayNr + 3);
+
+ // Store the millisecond value of the target date
+ const firstThursday = target.valueOf();
+
+ // Set the target to the first thursday of the year
+ // First set the target to january first
+ target.setMonth(0, 1);
+ // Not a thursday? Correct the date to the next thursday
+ if (target.getDay() !== 4) {
+ target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);
+ }
+
+ // The weeknumber is the number of weeks between the
+ // first thursday of the year and the thursday in the target week
+ return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000
+}
+
+module.exports = getWeek;
+
+},{}],7:[function(require,module,exports){
+const getURLOfUser = require('./getURLOfUser');
+
+const self = {};
+
+self._nodes = {
+ iframe: document.querySelector('iframe')
+};
+
+self.viewItem = function (offset, selectedUser) {
+ const url = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1);
+ self._nodes.iframe.src = url;
+};
+
+module.exports = self;
+
+},{"./getURLOfUser":5}],8:[function(require,module,exports){
const frontpage = require('./frontpage');
+require('./search');
frontpage.show();
document.body.style.opacity = 1;
-},{"./frontpage":1}]},{},[2])
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZnJvbnRwYWdlLmpzIiwicHVibGljL2phdmFzY3JpcHRzL21haW4uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQSxNQUFNLFlBQVksRUFBbEI7QUFDQSxNQUFNLE9BQU8sU0FBYjs7QUFFQSxLQUFLLE1BQUwsR0FBYztBQUNaLFVBQVEsU0FBUyxhQUFULENBQXVCLFNBQXZCLENBREk7QUFFWixTQUFPLFNBQVMsYUFBVCxDQUF1QixzQkFBdkI7QUFGSyxDQUFkOztBQUtBLEtBQUssT0FBTCxHQUFlLEtBQWY7O0FBRUEsS0FBSyxJQUFMLEdBQVksWUFBWTtBQUN0QixXQUFTLElBQVQsQ0FBYyxTQUFkLENBQXdCLEdBQXhCLENBQTRCLFVBQTVCO0FBQ0EsT0FBSyxPQUFMLEdBQWUsSUFBZjtBQUNELENBSEQ7O0FBS0EsS0FBSyxJQUFMLEdBQVksWUFBWTtBQUN0QixXQUFTLElBQVQsQ0FBYyxTQUFkLENBQXdCLE1BQXhCLENBQStCLFVBQS9CO0FBQ0EsT0FBSyxPQUFMLEdBQWUsS0FBZjtBQUNELENBSEQ7O0FBS0EsS0FBSyxNQUFMLENBQVksS0FBWixDQUFrQixnQkFBbEIsQ0FBbUMsT0FBbkMsRUFBNEMsS0FBSyxJQUFqRDs7QUFFQSxPQUFPLE9BQVAsR0FBaUIsU0FBakI7OztBQ3RCQSxNQUFNLFlBQVksUUFBUSxhQUFSLENBQWxCOztBQUVBLFVBQVUsSUFBVjs7QUFFQSxTQUFTLElBQVQsQ0FBYyxLQUFkLENBQW9CLE9BQXBCLEdBQThCLENBQTlCIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsImNvbnN0IGZyb250cGFnZSA9IHt9XG5jb25zdCBzZWxmID0gZnJvbnRwYWdlXG5cbnNlbGYuX25vZGVzID0ge1xuICBzZWFyY2g6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWFyY2gnKSxcbiAgaW5wdXQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0nKVxufVxuXG5zZWxmLmlzU2hvd24gPSBmYWxzZVxuXG5zZWxmLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnbm8taW5wdXQnKVxuICBzZWxmLmlzU2hvd24gPSB0cnVlXG59XG5cbnNlbGYuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCduby1pbnB1dCcpXG4gIHNlbGYuaXNTaG93biA9IGZhbHNlXG59XG5cbnNlbGYuX25vZGVzLmlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0Jywgc2VsZi5oaWRlKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZyb250cGFnZVxuIiwiY29uc3QgZnJvbnRwYWdlID0gcmVxdWlyZSgnLi9mcm9udHBhZ2UnKVxuXG5mcm9udHBhZ2Uuc2hvdygpXG5cbmRvY3VtZW50LmJvZHkuc3R5bGUub3BhY2l0eSA9IDFcbiJdfQ==
+},{"./frontpage":4,"./search":9}],9:[function(require,module,exports){
+const autocomplete = require('./autocomplete');
+const iframe = require('./iframe');
+
+const self = {};
+
+self._nodes = {
+ search: document.querySelector('#search'),
+ input: document.querySelector('input[type="search"]')
+};
+
+self.submit = function () {
+ self._nodes.input.blur();
+
+ const selectedItem = autocomplete.getSelectedItem();
+ console.log(selectedItem);
+ iframe.viewItem(0, selectedItem);
+};
+
+self._handleSubmit = function (event) {
+ event.preventDefault();
+ self.submit();
+};
+
+self._nodes.search.addEventListener('submit', self._handleSubmit);
+
+console.log(self);
+
+module.exports = self;
+
+},{"./autocomplete":3,"./iframe":7}]},{},[8])
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZnV6enkvbGliL2Z1enp5LmpzIiwibm9kZV9tb2R1bGVzL2xlZnQtcGFkL2luZGV4LmpzIiwicHVibGljL2phdmFzY3JpcHRzL2F1dG9jb21wbGV0ZS5qcyIsInB1YmxpYy9qYXZhc2NyaXB0cy9mcm9udHBhZ2UuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvZ2V0VVJMT2ZVc2VyLmpzIiwicHVibGljL2phdmFzY3JpcHRzL2dldFdlZWsuanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvaWZyYW1lLmpzIiwicHVibGljL2phdmFzY3JpcHRzL21haW4uanMiLCJwdWJsaWMvamF2YXNjcmlwdHMvc2VhcmNoLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QjtBQUNBLE1BQU0sU0FBUyxRQUFRLFVBQVIsQ0FBZjs7QUFFQSxNQUFNLE9BQU8sRUFBYjs7QUFFQSxLQUFLLE1BQUwsR0FBYztBQUNaLFVBQVEsU0FBUyxhQUFULENBQXVCLFNBQXZCLENBREk7QUFFWixTQUFPLFNBQVMsYUFBVCxDQUF1QixzQkFBdkI7QUFGSyxDQUFkOztBQUtBLEtBQUssTUFBTCxHQUFjLFlBQVk7QUFDeEIsT0FBSyxNQUFMLENBQVksS0FBWixDQUFrQixJQUFsQjs7QUFFQSxRQUFNLGVBQWUsYUFBYSxlQUFiLEVBQXJCO0FBQ0EsVUFBUSxHQUFSLENBQVksWUFBWjtBQUNBLFNBQU8sUUFBUCxDQUFnQixDQUFoQixFQUFtQixZQUFuQjtBQUNELENBTkQ7O0FBUUEsS0FBSyxhQUFMLEdBQXFCLFVBQVUsS0FBVixFQUFpQjtBQUNwQyxRQUFNLGNBQU47QUFDQSxPQUFLLE1BQUw7QUFDRCxDQUhEOztBQUtBLEtBQUssTUFBTCxDQUFZLE1BQVosQ0FBbUIsZ0JBQW5CLENBQW9DLFFBQXBDLEVBQThDLEtBQUssYUFBbkQ7O0FBRUEsUUFBUSxHQUFSLENBQVksSUFBWjs7QUFFQSxPQUFPLE9BQVAsR0FBaUIsSUFBakIiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLypcbiAqIEZ1enp5XG4gKiBodHRwczovL2dpdGh1Yi5jb20vbXlvcmsvZnV6enlcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTIgTWF0dCBZb3JrXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4gKi9cblxuKGZ1bmN0aW9uKCkge1xuXG52YXIgcm9vdCA9IHRoaXM7XG5cbnZhciBmdXp6eSA9IHt9O1xuXG4vLyBVc2UgaW4gbm9kZSBvciBpbiBicm93c2VyXG5pZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gZnV6enk7XG59IGVsc2Uge1xuICByb290LmZ1enp5ID0gZnV6enk7XG59XG5cbi8vIFJldHVybiBhbGwgZWxlbWVudHMgb2YgYGFycmF5YCB0aGF0IGhhdmUgYSBmdXp6eVxuLy8gbWF0Y2ggYWdhaW5zdCBgcGF0dGVybmAuXG5mdXp6eS5zaW1wbGVGaWx0ZXIgPSBmdW5jdGlvbihwYXR0ZXJuLCBhcnJheSkge1xuICByZXR1cm4gYXJyYXkuZmlsdGVyKGZ1bmN0aW9uKHN0cmluZykge1xuICAgIHJldHVybiBmdXp6eS50ZXN0KHBhdHRlcm4sIHN0cmluZyk7XG4gIH0pO1xufTtcblxuLy8gRG9lcyBgcGF0dGVybmAgZnV6enkgbWF0Y2ggYHN0cmluZ2A/XG5mdXp6eS50ZXN0ID0gZnVuY3Rpb24ocGF0dGVybiwgc3RyaW5nKSB7XG4gIHJldHVybiBmdXp6eS5tYXRjaChwYXR0ZXJuLCBzdHJpbmcpICE9PSBudWxsO1xufTtcblxuLy8gSWYgYHBhdHRlcm5gIG1hdGNoZXMgYHN0cmluZ2AsIHdyYXAgZWFjaCBtYXRjaGluZyBjaGFyYWN0ZXJcbi8vIGluIGBvcHRzLnByZWAgYW5kIGBvcHRzLnBvc3RgLiBJZiBubyBtYXRjaCwgcmV0dXJuIG51bGxcbmZ1enp5Lm1hdGNoID0gZnVuY3Rpb24ocGF0dGVybiwgc3RyaW5nLCBvcHRzKSB7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICB2YXIgcGF0dGVybklkeCA9IDBcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gICAgLCB0b3RhbFNjb3JlID0gMFxuICAgICwgY3VyclNjb3JlID0gMFxuICAgIC8vIHByZWZpeFxuICAgICwgcHJlID0gb3B0cy5wcmUgfHwgJydcbiAgICAvLyBzdWZmaXhcbiAgICAsIHBvc3QgPSBvcHRzLnBvc3QgfHwgJydcbiAgICAvLyBTdHJpbmcgdG8gY29tcGFyZSBhZ2FpbnN0LiBUaGlzIG1pZ2h0IGJlIGEgbG93ZXJjYXNlIHZlcnNpb24gb2YgdGhlXG4gICAgLy8gcmF3IHN0cmluZ1xuICAgICwgY29tcGFyZVN0cmluZyA9ICBvcHRzLmNhc2VTZW5zaXRpdmUgJiYgc3RyaW5nIHx8IHN0cmluZy50b0xvd2VyQ2FzZSgpXG4gICAgLCBjaCwgY29tcGFyZUNoYXI7XG5cbiAgcGF0dGVybiA9IG9wdHMuY2FzZVNlbnNpdGl2ZSAmJiBwYXR0ZXJuIHx8IHBhdHRlcm4udG9Mb3dlckNhc2UoKTtcblxuICAvLyBGb3IgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZywgZWl0aGVyIGFkZCBpdCB0byB0aGUgcmVzdWx0XG4gIC8vIG9yIHdyYXAgaW4gdGVtcGxhdGUgaWYgaXQncyB0aGUgbmV4dCBzdHJpbmcgaW4gdGhlIHBhdHRlcm5cbiAgZm9yKHZhciBpZHggPSAwOyBpZHggPCBsZW47IGlkeCsrKSB7XG4gICAgY2ggPSBzdHJpbmdbaWR4XTtcbiAgICBpZihjb21wYXJlU3RyaW5nW2lkeF0gPT09IHBhdHRlcm5bcGF0dGVybklkeF0pIHtcbiAgICAgIGNoID0gcHJlICsgY2ggKyBwb3N0O1xuICAgICAgcGF0dGVybklkeCArPSAxO1xuXG4gICAgICAvLyBjb25zZWN1dGl2ZSBjaGFyYWN0ZXJzIHNob3VsZCBpbmNyZWFzZSB0aGUgc2NvcmUgbW9yZSB0aGFuIGxpbmVhcmx5XG4gICAgICBjdXJyU2NvcmUgKz0gMSArIGN1cnJTY29yZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VyclNjb3JlID0gMDtcbiAgICB9XG4gICAgdG90YWxTY29yZSArPSBjdXJyU2NvcmU7XG4gICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gY2g7XG4gIH1cblxuICAvLyByZXR1cm4gcmVuZGVyZWQgc3RyaW5nIGlmIHdlIGhhdmUgYSBtYXRjaCBmb3IgZXZlcnkgY2hhclxuICBpZihwYXR0ZXJuSWR4ID09PSBwYXR0ZXJuLmxlbmd0aCkge1xuICAgIHJldHVybiB7cmVuZGVyZWQ6IHJlc3VsdC5qb2luKCcnKSwgc2NvcmU6IHRvdGFsU2NvcmV9O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBUaGUgbm9ybWFsIGVudHJ5IHBvaW50LiBGaWx0ZXJzIGBhcnJgIGZvciBtYXRjaGVzIGFnYWluc3QgYHBhdHRlcm5gLlxuLy8gSXQgcmV0dXJucyBhbiBhcnJheSB3aXRoIG1hdGNoaW5nIHZhbHVlcyBvZiB0aGUgdHlwZTpcbi8vXG4vLyAgICAgW3tcbi8vICAgICAgICAgc3RyaW5nOiAgICc8Yj5sYWgnIC8vIFRoZSByZW5kZXJlZCBzdHJpbmdcbi8vICAgICAgICwgaW5kZXg6ICAgIDIgICAgICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBpbiBgYXJyYFxuLy8gICAgICAgLCBvcmlnaW5hbDogJ2JsYWgnICAgLy8gVGhlIG9yaWdpbmFsIGVsZW1lbnQgaW4gYGFycmBcbi8vICAgICB9XVxuLy9cbi8vIGBvcHRzYCBpcyBhbiBvcHRpb25hbCBhcmd1bWVudCBiYWcuIERldGFpbHM6XG4vL1xuLy8gICAgb3B0cyA9IHtcbi8vICAgICAgICAvLyBzdHJpbmcgdG8gcHV0IGJlZm9yZSBhIG1hdGNoaW5nIGNoYXJhY3RlclxuLy8gICAgICAgIHByZTogICAgICc8Yj4nXG4vL1xuLy8gICAgICAgIC8vIHN0cmluZyB0byBwdXQgYWZ0ZXIgbWF0Y2hpbmcgY2hhcmFjdGVyXG4vLyAgICAgICwgcG9zdDogICAgJzwvYj4nXG4vL1xuLy8gICAgICAgIC8vIE9wdGlvbmFsIGZ1bmN0aW9uLiBJbnB1dCBpcyBhbiBlbnRyeSBpbiB0aGUgZ2l2ZW4gYXJyYCxcbi8vICAgICAgICAvLyBvdXRwdXQgc2hvdWxkIGJlIHRoZSBzdHJpbmcgdG8gdGVzdCBgcGF0dGVybmAgYWdhaW5zdC5cbi8vICAgICAgICAvLyBJbiB0aGlzIGV4YW1wbGUsIGlmIGBhcnIgPSBbe2NyeWluZzogJ2tvYWxhJ31dYCB3ZSB3b3VsZCByZXR1cm5cbi8vICAgICAgICAvLyAna29hbGEnLlxuLy8gICAgICAsIGV4dHJhY3Q6IGZ1bmN0aW9uKGFyZykgeyByZXR1cm4gYXJnLmNyeWluZzsgfVxuLy8gICAgfVxuZnV6enkuZmlsdGVyID0gZnVuY3Rpb24ocGF0dGVybiwgYXJyLCBvcHRzKSB7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICByZXR1cm4gYXJyXG4gICAgLnJlZHVjZShmdW5jdGlvbihwcmV2LCBlbGVtZW50LCBpZHgsIGFycikge1xuICAgICAgdmFyIHN0ciA9IGVsZW1lbnQ7XG4gICAgICBpZihvcHRzLmV4dHJhY3QpIHtcbiAgICAgICAgc3RyID0gb3B0cy5leHRyYWN0KGVsZW1lbnQpO1xuICAgICAgfVxuICAgICAgdmFyIHJlbmRlcmVkID0gZnV6enkubWF0Y2gocGF0dGVybiwgc3RyLCBvcHRzKTtcbiAgICAgIGlmKHJlbmRlcmVkICE9IG51bGwpIHtcbiAgICAgICAgcHJldltwcmV2Lmxlbmd0aF0gPSB7XG4gICAgICAgICAgICBzdHJpbmc6IHJlbmRlcmVkLnJlbmRlcmVkXG4gICAgICAgICAgLCBzY29yZTogcmVuZGVyZWQuc2NvcmVcbiAgICAgICAgICAsIGluZGV4OiBpZHhcbiAgICAgICAgICAsIG9yaWdpbmFsOiBlbGVtZW50XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJldjtcbiAgICB9LCBbXSlcblxuICAgIC8vIFNvcnQgYnkgc2NvcmUuIEJyb3dzZXJzIGFyZSBpbmNvbnNpc3RlbnQgd3J0IHN0YWJsZS91bnN0YWJsZVxuICAgIC8vIHNvcnRpbmcsIHNvIGZvcmNlIHN0YWJsZSBieSB1c2luZyB0aGUgaW5kZXggaW4gdGhlIGNhc2Ugb2YgdGllLlxuICAgIC8vIFNlZSBodHRwOi8vb2ZiLm5ldC9+c2V0aG1sL2lzLXNvcnQtc3RhYmxlLmh0bWxcbiAgICAuc29ydChmdW5jdGlvbihhLGIpIHtcbiAgICAgIHZhciBjb21wYXJlID0gYi5zY29yZSAtIGEuc2NvcmU7XG4gICAgICBpZihjb21wYXJlKSByZXR1cm4gY29tcGFyZTtcbiAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICB9KTtcbn07XG5cblxufSgpKTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xubW9kdWxlLmV4cG9ydHMgPSBsZWZ0UGFkO1xuXG52YXIgY2FjaGUgPSBbXG4gICcnLFxuICAnICcsXG4gICcgICcsXG4gICcgICAnLFxuICAnICAgICcsXG4gICcgICAgICcsXG4gICcgICAgICAnLFxuICAnICAgICAgICcsXG4gICcgICAgICAgICcsXG4gICcgICAgICAgICAnXG5dO1xuXG5mdW5jdGlvbiBsZWZ0UGFkIChzdHIsIGxlbiwgY2gpIHtcbiAgLy8gY29udmVydCBgc3RyYCB0byBgc3RyaW5nYFxuICBzdHIgPSBzdHIgKyAnJztcbiAgLy8gYGxlbmAgaXMgdGhlIGBwYWRgJ3MgbGVuZ3RoIG5vd1xuICBsZW4gPSBsZW4gLSBzdHIubGVuZ3RoO1xuICAvLyBkb2Vzbid0IG5lZWQgdG8gcGFkXG4gIGlmIChsZW4gPD0gMCkgcmV0dXJuIHN0cjtcbiAgLy8gYGNoYCBkZWZhdWx0cyB0byBgJyAnYFxuICBpZiAoIWNoICYmIGNoICE9PSAwKSBjaCA9ICcgJztcbiAgLy8gY29udmVydCBgY2hgIHRvIGBzdHJpbmdgXG4gIGNoID0gY2ggKyAnJztcbiAgLy8gY2FjaGUgY29tbW9uIHVzZSBjYXNlc1xuICBpZiAoY2ggPT09ICcgJyAmJiBsZW4gPCAxMCkgcmV0dXJuIGNhY2hlW2xlbl0gKyBzdHI7XG4gIC8vIGBwYWRgIHN0YXJ0cyB3aXRoIGFuIGVtcHR5IHN0cmluZ1xuICB2YXIgcGFkID0gJyc7XG4gIC8vIGxvb3BcbiAgd2hpbGUgKHRydWUpIHtcbiAgICAvLyBhZGQgYGNoYCB0byBgcGFkYCBpZiBgbGVuYCBpcyBvZGRcbiAgICBpZiAobGVuICYgMSkgcGFkICs9IGNoO1xuICAgIC8vIGRldmlkZSBgbGVuYCBieSAyLCBkaXRjaCB0aGUgZnJhY3Rpb25cbiAgICBsZW4gPj49IDE7XG4gICAgLy8gXCJkb3VibGVcIiB0aGUgYGNoYCBzbyB0aGlzIG9wZXJhdGlvbiBjb3VudCBncm93cyBsb2dhcml0aG1pY2FsbHkgb24gYGxlbmBcbiAgICAvLyBlYWNoIHRpbWUgYGNoYCBpcyBcImRvdWJsZWRcIiwgdGhlIGBsZW5gIHdvdWxkIG5lZWQgdG8gYmUgXCJkb3VibGVkXCIgdG9vXG4gICAgLy8gc2ltaWxhciB0byBmaW5kaW5nIGEgdmFsdWUgaW4gYmluYXJ5IHNlYXJjaCB0cmVlLCBoZW5jZSBPKGxvZyhuKSlcbiAgICBpZiAobGVuKSBjaCArPSBjaDtcbiAgICAvLyBgbGVuYCBpcyAwLCBleGl0IHRoZSBsb29wXG4gICAgZWxzZSBicmVhaztcbiAgfVxuICAvLyBwYWQgYHN0cmAhXG4gIHJldHVybiBwYWQgKyBzdHI7XG59XG4iLCIvKiBnbG9iYWwgVVNFUlMgKi9cblxuY29uc3QgZnV6enkgPSByZXF1aXJlKCdmdXp6eScpXG5jb25zdCBzZWFyY2ggPSByZXF1aXJlKCcuL3NlYXJjaCcpXG5cbmNvbnN0IHNlbGYgPSB7fVxuXG5zZWxmLl9pdGVtcyA9IFtdXG5zZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCA9IC0xXG5cbnNlbGYuX25vZGVzID0ge1xuICBmb3JtOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoJyksXG4gIGlucHV0OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJyksXG4gIGF1dG9jb21wbGV0ZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmF1dG9jb21wbGV0ZScpXG59XG5cbnNlbGYuZ2V0U2VsZWN0ZWRJdGVtID0gZnVuY3Rpb24gKCkge1xuICBpZiAoc2VsZi5nZXRJdGVtcygpID09PSBbXSkgcmV0dXJuXG5cbiAgaWYgKHNlbGYuZ2V0U2VsZWN0ZWRJdGVtSW5kZXgoKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gc2VsZi5nZXRJdGVtcygpWzBdXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHNlbGYuZ2V0SXRlbXMoKVtzZWxmLmdldFNlbGVjdGVkSXRlbUluZGV4KCldXG4gIH1cbn1cblxuc2VsZi5nZXRTZWxlY3RlZEl0ZW1JbmRleCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4XG59XG5cbnNlbGYuZ2V0SXRlbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBzZWxmLl9pdGVtc1xufVxuXG5zZWxmLl9yZW1vdmVBbGxJdGVtcyA9IGZ1bmN0aW9uICgpIHtcbiAgd2hpbGUgKHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5maXJzdENoaWxkKSB7XG4gICAgc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLnJlbW92ZUNoaWxkKHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5maXJzdENoaWxkKVxuICB9XG4gIHNlbGYuX2l0ZW1zID0gW11cbiAgc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggPSAtMVxufVxuXG5zZWxmLl9hZGRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgY29uc3QgbGlzdEl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpXG4gIGxpc3RJdGVtLnRleHRDb250ZW50ID0gaXRlbS52YWx1ZVxuICBsaXN0SXRlbS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHNlbGYuX2hhbmRsZUl0ZW1DbGljaylcbiAgc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmFwcGVuZENoaWxkKGxpc3RJdGVtKVxuICBzZWxmLl9pdGVtcy5wdXNoKGl0ZW0pXG59XG5cbnNlbGYuX21vdmVTZWxlY3RlZCA9IGZ1bmN0aW9uIChzaGlmdCkge1xuICBpZiAoc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggKyBzaGlmdCA+PSBzZWxmLmdldEl0ZW1zKCkubGVuZ3RoKSB7XG4gICAgc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggPSAtMVxuICB9IGVsc2UgaWYgKHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ICsgc2hpZnQgPCAtMSkge1xuICAgIHNlbGYuX3NlbGVjdGVkSXRlbUluZGV4ID0gc2VsZi5nZXRJdGVtcygpLmxlbmd0aCAtIDFcbiAgfSBlbHNlIHtcbiAgICBzZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCArPSBzaGlmdFxuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmdldEl0ZW1zKCkubGVuZ3RoOyBpKyspIHtcbiAgICBzZWxmLl9ub2Rlcy5hdXRvY29tcGxldGUuY2hpbGRyZW5baV0uY2xhc3NMaXN0LnJlbW92ZSgnc2VsZWN0ZWQnKVxuICB9XG4gIGlmIChzZWxmLl9zZWxlY3RlZEl0ZW1JbmRleCA+PSAwKSB7XG4gICAgc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlXG4gICAgICAgIC5jaGlsZHJlbltzZWxmLl9zZWxlY3RlZEl0ZW1JbmRleF0uY2xhc3NMaXN0LmFkZCgnc2VsZWN0ZWQnKVxuICB9XG59XG5cbnNlbGYuX2NhbGN1bGF0ZSA9IGZ1bmN0aW9uIChzZWFyY2hUZXJtKSB7XG4gIGNvbnN0IGFsbFJlc3VsdHMgPSBmdXp6eS5maWx0ZXIoc2VhcmNoVGVybSwgVVNFUlMsIHtcbiAgICBleHRyYWN0OiBpdGVtID0+IGl0ZW0udmFsdWVcbiAgfSlcbiAgY29uc3QgZmlyc3RSZXN1bHRzID0gYWxsUmVzdWx0cy5zbGljZSgwLCA3KVxuXG4gIGNvbnN0IG9yaWdpbmFsUmVzdWx0cyA9IGZpcnN0UmVzdWx0cy5tYXAocmVzdWx0ID0+IHJlc3VsdC5vcmlnaW5hbClcblxuICByZXR1cm4gb3JpZ2luYWxSZXN1bHRzXG59XG5cbnNlbGYuX2hhbmRsZUl0ZW1DbGljayA9IGZ1bmN0aW9uIChldmVudCkge1xuICBjb25zdCBpdGVtSW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZlxuICAgICAgLmNhbGwoc2VsZi5fbm9kZXMuYXV0b2NvbXBsZXRlLmNoaWxkcmVuLCBldmVudC50YXJnZXQpXG4gIGNvbnNvbGUubG9nKGl0ZW1JbmRleClcbiAgc2VsZi5fc2VsZWN0ZWRJdGVtSW5kZXggPSBpdGVtSW5kZXhcbiAgY29uc29sZS5sb2coc2VhcmNoKVxuICBzZWFyY2guc3VibWl0KClcbn1cblxuc2VsZi5faGFuZGxlRm9jdXMgPSBmdW5jdGlvbiAoKSB7XG4gIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xufVxuXG5zZWxmLl9oYW5kbGVCbHVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIC8vIGNvbnNvbGUubG9nKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJzpmb2N1cycpKVxuICAvLyBpZiAoZXZlbnQudGFyZ2V0LnBhcmVudE5vZGUgPT09IHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZSkgcmV0dXJuXG4gIC8vIHNlbGYuX25vZGVzLmF1dG9jb21wbGV0ZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG59XG5cbnNlbGYuX2hhbmRsZVRleHRVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBzZWxmLl9jYWxjdWxhdGUoc2VsZi5fbm9kZXMuaW5wdXQudmFsdWUpXG5cbiAgc2VsZi5fcmVtb3ZlQWxsSXRlbXMoKVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICBzZWxmLl9hZGRJdGVtKHJlc3VsdHNbaV0pXG4gIH1cbn1cblxuc2VsZi5faGFuZGxlS2V5ZG93biA9IGZ1bmN0aW9uIChldmVudCkge1xuICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKDEpXG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgc2VsZi5fbW92ZVNlbGVjdGVkKC0xKVxuICAgIH1cbiAgfVxufVxuXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHNlbGYuX2hhbmRsZUZvY3VzKVxuc2VsZi5fbm9kZXMuaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIHNlbGYuX2hhbmRsZUJsdXIpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHNlbGYuX2hhbmRsZVRleHRVcGRhdGUpXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgc2VsZi5faGFuZGxlS2V5ZG93bilcblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCJjb25zdCBzZWxmID0ge31cblxuc2VsZi5fbm9kZXMgPSB7XG4gIGlucHV0OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwic2VhcmNoXCJdJylcbn1cblxuc2VsZi5pc1Nob3duID0gZmFsc2Vcblxuc2VsZi5zaG93ID0gZnVuY3Rpb24gKCkge1xuICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ25vLWlucHV0JylcbiAgc2VsZi5pc1Nob3duID0gdHJ1ZVxufVxuXG5zZWxmLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnbm8taW5wdXQnKVxuICBzZWxmLmlzU2hvd24gPSBmYWxzZVxufVxuXG5zZWxmLl9ub2Rlcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHNlbGYuaGlkZSlcblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCJ2YXIgbGVmdFBhZCA9IHJlcXVpcmUoJ2xlZnQtcGFkJylcbnZhciBnZXRXZWVrID0gcmVxdWlyZSgnLi9nZXRXZWVrJylcblxuZnVuY3Rpb24gZ2V0VVJMT2ZVc2VycyAod2Vla09mZnNldCwgdHlwZSwgaWQpIHtcbiAgcmV0dXJuIGAvLyR7d2luZG93LmxvY2F0aW9uLmhvc3R9L21lZXRpbmdwb2ludFByb3h5L1Jvb3N0ZXJzLUFMJTJGZG9jJTJGZGFncm9vc3RlcnMlMkZgICtcbiAgICAgIGAkeyhnZXRXZWVrKCkgKyB3ZWVrT2Zmc2V0KX0lMkYke3R5cGV9JTJGJHt0eXBlfSR7bGVmdFBhZChpZCwgNSwgJzAnKX0uaHRtYFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFVSTE9mVXNlcnNcbiIsIi8vIGNvcGllZCBmcm9tIGh0dHA6Ly93d3cubWVldGluZ3BvaW50bWNvLm5sL1Jvb3N0ZXJzLUFML2RvYy9kYWdyb29zdGVycy91bnRpc3NjcmlwdHMuanMsXG4vLyB3ZXJlIHVzaW5nIHRoZSBzYW1lIGNvZGUgYXMgdGhleSBkbyB0byBiZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGdldCB0aGUgc2FtZVxuLy8gd2VlayBudW1iZXIuXG5mdW5jdGlvbiBnZXRXZWVrICgpIHtcbiAgLy8gQ3JlYXRlIGEgY29weSBvZiB0aGlzIGRhdGUgb2JqZWN0XG4gIGNvbnN0IHRhcmdldCA9IG5ldyBEYXRlKClcblxuICAvLyBJU08gd2VlayBkYXRlIHdlZWtzIHN0YXJ0IG9uIG1vbmRheVxuICAvLyBzbyBjb3JyZWN0IHRoZSBkYXkgbnVtYmVyXG4gIGNvbnN0IGRheU5yID0gKHRhcmdldC5nZXREYXkoKSArIDYpICUgN1xuXG4gIC8vIElTTyA4NjAxIHN0YXRlcyB0aGF0IHdlZWsgMSBpcyB0aGUgd2Vla1xuICAvLyB3aXRoIHRoZSBmaXJzdCB0aHVyc2RheSBvZiB0aGF0IHllYXIuXG4gIC8vIFNldCB0aGUgdGFyZ2V0IGRhdGUgdG8gdGhlIHRodXJzZGF5IGluIHRoZSB0YXJnZXQgd2Vla1xuICB0YXJnZXQuc2V0RGF0ZSh0YXJnZXQuZ2V0RGF0ZSgpIC0gZGF5TnIgKyAzKVxuXG4gIC8vIFN0b3JlIHRoZSBtaWxsaXNlY29uZCB2YWx1ZSBvZiB0aGUgdGFyZ2V0IGRhdGVcbiAgY29uc3QgZmlyc3RUaHVyc2RheSA9IHRhcmdldC52YWx1ZU9mKClcblxuICAvLyBTZXQgdGhlIHRhcmdldCB0byB0aGUgZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXJcbiAgLy8gRmlyc3Qgc2V0IHRoZSB0YXJnZXQgdG8gamFudWFyeSBmaXJzdFxuICB0YXJnZXQuc2V0TW9udGgoMCwgMSlcbiAgLy8gTm90IGEgdGh1cnNkYXk/IENvcnJlY3QgdGhlIGRhdGUgdG8gdGhlIG5leHQgdGh1cnNkYXlcbiAgaWYgKHRhcmdldC5nZXREYXkoKSAhPT0gNCkge1xuICAgIHRhcmdldC5zZXRNb250aCgwLCAxICsgKCg0IC0gdGFyZ2V0LmdldERheSgpKSArIDcpICUgNylcbiAgfVxuXG4gIC8vIFRoZSB3ZWVrbnVtYmVyIGlzIHRoZSBudW1iZXIgb2Ygd2Vla3MgYmV0d2VlbiB0aGVcbiAgLy8gZmlyc3QgdGh1cnNkYXkgb2YgdGhlIHllYXIgYW5kIHRoZSB0aHVyc2RheSBpbiB0aGUgdGFyZ2V0IHdlZWtcbiAgcmV0dXJuIDEgKyBNYXRoLmNlaWwoKGZpcnN0VGh1cnNkYXkgLSB0YXJnZXQpIC8gNjA0ODAwMDAwKSAvLyA2MDQ4MDAwMDAgPSA3ICogMjQgKiAzNjAwICogMTAwMFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFdlZWtcbiIsImNvbnN0IGdldFVSTE9mVXNlciA9IHJlcXVpcmUoJy4vZ2V0VVJMT2ZVc2VyJylcblxuY29uc3Qgc2VsZiA9IHt9XG5cbnNlbGYuX25vZGVzID0ge1xuICBpZnJhbWU6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lmcmFtZScpXG59XG5cbnNlbGYudmlld0l0ZW0gPSBmdW5jdGlvbiAob2Zmc2V0LCBzZWxlY3RlZFVzZXIpIHtcbiAgY29uc3QgdXJsID0gZ2V0VVJMT2ZVc2VyKG9mZnNldCwgc2VsZWN0ZWRVc2VyLnR5cGUsIHNlbGVjdGVkVXNlci5pbmRleCArIDEpXG4gIHNlbGYuX25vZGVzLmlmcmFtZS5zcmMgPSB1cmxcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZWxmXG4iLCJjb25zdCBmcm9udHBhZ2UgPSByZXF1aXJlKCcuL2Zyb250cGFnZScpXG5yZXF1aXJlKCcuL3NlYXJjaCcpXG5cbmZyb250cGFnZS5zaG93KClcblxuZG9jdW1lbnQuYm9keS5zdHlsZS5vcGFjaXR5ID0gMVxuIiwiY29uc3QgYXV0b2NvbXBsZXRlID0gcmVxdWlyZSgnLi9hdXRvY29tcGxldGUnKVxuY29uc3QgaWZyYW1lID0gcmVxdWlyZSgnLi9pZnJhbWUnKVxuXG5jb25zdCBzZWxmID0ge31cblxuc2VsZi5fbm9kZXMgPSB7XG4gIHNlYXJjaDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NlYXJjaCcpLFxuICBpbnB1dDogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1cInNlYXJjaFwiXScpXG59XG5cbnNlbGYuc3VibWl0ID0gZnVuY3Rpb24gKCkge1xuICBzZWxmLl9ub2Rlcy5pbnB1dC5ibHVyKClcblxuICBjb25zdCBzZWxlY3RlZEl0ZW0gPSBhdXRvY29tcGxldGUuZ2V0U2VsZWN0ZWRJdGVtKClcbiAgY29uc29sZS5sb2coc2VsZWN0ZWRJdGVtKVxuICBpZnJhbWUudmlld0l0ZW0oMCwgc2VsZWN0ZWRJdGVtKVxufVxuXG5zZWxmLl9oYW5kbGVTdWJtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICBzZWxmLnN1Ym1pdCgpXG59XG5cbnNlbGYuX25vZGVzLnNlYXJjaC5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCBzZWxmLl9oYW5kbGVTdWJtaXQpXG5cbmNvbnNvbGUubG9nKHNlbGYpXG5cbm1vZHVsZS5leHBvcnRzID0gc2VsZlxuIl19
diff --git a/public/javascripts/frontpage.js b/public/javascripts/frontpage.js
index 3c9093e..d789045 100644
--- a/public/javascripts/frontpage.js
+++ b/public/javascripts/frontpage.js
@@ -1,5 +1,4 @@
-const frontpage = {}
-const self = frontpage
+const self = {}
self._nodes = {
input: document.querySelector('input[type="search"]')
@@ -19,4 +18,4 @@ self.hide = function () {
self._nodes.input.addEventListener('input', self.hide)
-module.exports = frontpage
+module.exports = self
diff --git a/public/javascripts/iframe.js b/public/javascripts/iframe.js
new file mode 100644
index 0000000..e3296be
--- /dev/null
+++ b/public/javascripts/iframe.js
@@ -0,0 +1,14 @@
+const getURLOfUser = require('./getURLOfUser')
+
+const self = {}
+
+self._nodes = {
+ iframe: document.querySelector('iframe')
+}
+
+self.viewItem = function (offset, selectedUser) {
+ const url = getURLOfUser(offset, selectedUser.type, selectedUser.index + 1)
+ self._nodes.iframe.src = url
+}
+
+module.exports = self
diff --git a/public/javascripts/main.js b/public/javascripts/main.js
index 549427e..d242ce2 100644
--- a/public/javascripts/main.js
+++ b/public/javascripts/main.js
@@ -1,4 +1,5 @@
const frontpage = require('./frontpage')
+require('./search')
frontpage.show()
diff --git a/public/javascripts/search.js b/public/javascripts/search.js
new file mode 100644
index 0000000..8887ab2
--- /dev/null
+++ b/public/javascripts/search.js
@@ -0,0 +1,28 @@
+const autocomplete = require('./autocomplete')
+const iframe = require('./iframe')
+
+const self = {}
+
+self._nodes = {
+ search: document.querySelector('#search'),
+ input: document.querySelector('input[type="search"]')
+}
+
+self.submit = function () {
+ self._nodes.input.blur()
+
+ const selectedItem = autocomplete.getSelectedItem()
+ console.log(selectedItem)
+ iframe.viewItem(0, selectedItem)
+}
+
+self._handleSubmit = function (event) {
+ event.preventDefault()
+ self.submit()
+}
+
+self._nodes.search.addEventListener('submit', self._handleSubmit)
+
+console.log(self)
+
+module.exports = self