summaryrefslogtreecommitdiff
path: root/searx/static/themes/simple/src
diff options
context:
space:
mode:
authorAlexandre Flament <alex@al-f.net>2021-06-16 09:28:45 +0200
committerAlexandre Flament <alex@al-f.net>2021-06-16 12:38:06 +0200
commit6b80c57a3c04d6be37ae3c880f7e269fc362b107 (patch)
treeec3009353dfd713f9d91cf074b10f5d7a6bdcd5a /searx/static/themes/simple/src
parent49ea5b764454b4cd00eef67898b1c73ce3c28f31 (diff)
downloadsearxng-6b80c57a3c04d6be37ae3c880f7e269fc362b107.tar.gz
searxng-6b80c57a3c04d6be37ae3c880f7e269fc362b107.zip
[mod] simple theme: move source files to the src directory
Diffstat (limited to 'searx/static/themes/simple/src')
-rw-r--r--searx/static/themes/simple/src/js/head/00_init.js40
-rw-r--r--searx/static/themes/simple/src/js/main/00_searx_toolkit.js164
-rw-r--r--searx/static/themes/simple/src/js/main/searx_keyboard.js366
-rw-r--r--searx/static/themes/simple/src/js/main/searx_mapresult.js89
-rw-r--r--searx/static/themes/simple/src/js/main/searx_results.js63
-rw-r--r--searx/static/themes/simple/src/js/main/searx_search.js121
-rw-r--r--searx/static/themes/simple/src/less/autocomplete.less69
-rw-r--r--searx/static/themes/simple/src/less/code.less8
-rw-r--r--searx/static/themes/simple/src/less/definitions.less138
-rw-r--r--searx/static/themes/simple/src/less/index.less43
-rw-r--r--searx/static/themes/simple/src/less/ion.less181
-rw-r--r--searx/static/themes/simple/src/less/mixins.less62
-rw-r--r--searx/static/themes/simple/src/less/normalize.less341
-rw-r--r--searx/static/themes/simple/src/less/preferences.less103
-rw-r--r--searx/static/themes/simple/src/less/pygments.less99
-rw-r--r--searx/static/themes/simple/src/less/search.less264
-rw-r--r--searx/static/themes/simple/src/less/style-rtl.less6
-rw-r--r--searx/static/themes/simple/src/less/style.less762
-rw-r--r--searx/static/themes/simple/src/less/toolkit.less553
-rw-r--r--searx/static/themes/simple/src/less/toolkit_loader.less41
20 files changed, 3513 insertions, 0 deletions
diff --git a/searx/static/themes/simple/src/js/head/00_init.js b/searx/static/themes/simple/src/js/head/00_init.js
new file mode 100644
index 000000000..be7560451
--- /dev/null
+++ b/searx/static/themes/simple/src/js/head/00_init.js
@@ -0,0 +1,40 @@
+/**
+* searx is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* searx is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
+*
+* (C) 2019 by Alexandre Flament
+*
+*/
+(function(w, d) {
+ 'use strict';
+
+ // add data- properties
+ var script = d.currentScript || (function() {
+ var scripts = d.getElementsByTagName('script');
+ return scripts[scripts.length - 1];
+ })();
+
+ // try to detect touch screen
+ w.searx = {
+ touch: (("ontouchstart" in w) || w.DocumentTouch && document instanceof DocumentTouch) || false,
+ method: script.getAttribute('data-method'),
+ autocompleter: script.getAttribute('data-autocompleter') === 'true',
+ search_on_category_select: script.getAttribute('data-search-on-category-select') === 'true',
+ infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',
+ static_path: script.getAttribute('data-static-path'),
+ translations: JSON.parse(script.getAttribute('data-translations')),
+ };
+
+ // update the css
+ d.getElementsByTagName("html")[0].className = (w.searx.touch)?"js touch":"js";
+})(window, document); \ No newline at end of file
diff --git a/searx/static/themes/simple/src/js/main/00_searx_toolkit.js b/searx/static/themes/simple/src/js/main/00_searx_toolkit.js
new file mode 100644
index 000000000..dbef4be73
--- /dev/null
+++ b/searx/static/themes/simple/src/js/main/00_searx_toolkit.js
@@ -0,0 +1,164 @@
+/**
+* searx is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* searx is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
+*
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
+*
+*/
+window.searx = (function(w, d) {
+
+ 'use strict';
+
+ // not invented here tookit with bugs fixed elsewhere
+ // purposes : be just good enough and as small as possible
+
+ // from https://plainjs.com/javascript/events/live-binding-event-handlers-14/
+ if (w.Element) {
+ (function(ElementPrototype) {
+ ElementPrototype.matches = ElementPrototype.matches ||
+ ElementPrototype.matchesSelector ||
+ ElementPrototype.webkitMatchesSelector ||
+ ElementPrototype.msMatchesSelector ||
+ function(selector) {
+ var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
+ while (nodes[++i] && nodes[i] != node);
+ return !!nodes[i];
+ };
+ })(Element.prototype);
+ }
+
+ function callbackSafe(callback, el, e) {
+ try {
+ callback.call(el, e);
+ } catch (exception) {
+ console.log(exception);
+ }
+ }
+
+ var searx = window.searx || {};
+
+ searx.on = function(obj, eventType, callback, useCapture) {
+ useCapture = useCapture || false;
+ if (typeof obj !== 'string') {
+ // obj HTMLElement, HTMLDocument
+ obj.addEventListener(eventType, callback, useCapture);
+ } else {
+ // obj is a selector
+ d.addEventListener(eventType, function(e) {
+ var el = e.target || e.srcElement, found = false;
+ while (el && el.matches && el !== d && !(found = el.matches(obj))) el = el.parentElement;
+ if (found) callbackSafe(callback, el, e);
+ }, useCapture);
+ }
+ };
+
+ searx.ready = function(callback) {
+ if (document.readyState != 'loading') {
+ callback.call(w);
+ } else {
+ w.addEventListener('DOMContentLoaded', callback.bind(w));
+ }
+ };
+
+ searx.http = function(method, url, callback) {
+ var req = new XMLHttpRequest(),
+ resolve = function() {},
+ reject = function() {},
+ promise = {
+ then: function(callback) { resolve = callback; return promise; },
+ catch: function(callback) { reject = callback; return promise; }
+ };
+
+ try {
+ req.open(method, url, true);
+
+ // On load
+ req.onload = function() {
+ if (req.status == 200) {
+ resolve(req.response, req.responseType);
+ } else {
+ reject(Error(req.statusText));
+ }
+ };
+
+ // Handle network errors
+ req.onerror = function() {
+ reject(Error("Network Error"));
+ };
+
+ req.onabort = function() {
+ reject(Error("Transaction is aborted"));
+ };
+
+ // Make the request
+ req.send();
+ } catch (ex) {
+ reject(ex);
+ }
+
+ return promise;
+ };
+
+ searx.loadStyle = function(src) {
+ var path = searx.static_path + src,
+ id = "style_" + src.replace('.', '_'),
+ s = d.getElementById(id);
+ if (s === null) {
+ s = d.createElement('link');
+ s.setAttribute('id', id);
+ s.setAttribute('rel', 'stylesheet');
+ s.setAttribute('type', 'text/css');
+ s.setAttribute('href', path);
+ d.body.appendChild(s);
+ }
+ };
+
+ searx.loadScript = function(src, callback) {
+ var path = searx.static_path + src,
+ id = "script_" + src.replace('.', '_'),
+ s = d.getElementById(id);
+ if (s === null) {
+ s = d.createElement('script');
+ s.setAttribute('id', id);
+ s.setAttribute('src', path);
+ s.onload = callback;
+ s.onerror = function() {
+ s.setAttribute('error', '1');
+ };
+ d.body.appendChild(s);
+ } else if (!s.hasAttribute('error')) {
+ try {
+ callback.apply(s, []);
+ } catch (exception) {
+ console.log(exception);
+ }
+ } else {
+ console.log("callback not executed : script '" + path + "' not loaded.");
+ }
+ };
+
+ searx.insertBefore = function (newNode, referenceNode) {
+ element.parentNode.insertBefore(newNode, referenceNode);
+ };
+
+ searx.insertAfter = function(newNode, referenceNode) {
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+ };
+
+ searx.on('.close', 'click', function(e) {
+ var el = e.target || e.srcElement;
+ this.parentNode.classList.add('invisible');
+ });
+
+ return searx;
+})(window, document);
diff --git a/searx/static/themes/simple/src/js/main/searx_keyboard.js b/searx/static/themes/simple/src/js/main/searx_keyboard.js
new file mode 100644
index 000000000..657d9ec93
--- /dev/null
+++ b/searx/static/themes/simple/src/js/main/searx_keyboard.js
@@ -0,0 +1,366 @@
+searx.ready(function() {
+
+ searx.on('.result', 'click', function() {
+ highlightResult(this)(true);
+ });
+
+ searx.on('.result a', 'focus', function(e) {
+ var el = e.target;
+ while (el !== undefined) {
+ if (el.classList.contains('result')) {
+ if (el.getAttribute("data-vim-selected") === null) {
+ highlightResult(el)(true);
+ }
+ break;
+ }
+ el = el.parentNode;
+ }
+ }, true);
+
+ var vimKeys = {
+ 27: {
+ key: 'Escape',
+ fun: removeFocus,
+ des: 'remove focus from the focused input',
+ cat: 'Control'
+ },
+ 73: {
+ key: 'i',
+ fun: searchInputFocus,
+ des: 'focus on the search input',
+ cat: 'Control'
+ },
+ 66: {
+ key: 'b',
+ fun: scrollPage(-window.innerHeight),
+ des: 'scroll one page up',
+ cat: 'Navigation'
+ },
+ 70: {
+ key: 'f',
+ fun: scrollPage(window.innerHeight),
+ des: 'scroll one page down',
+ cat: 'Navigation'
+ },
+ 85: {
+ key: 'u',
+ fun: scrollPage(-window.innerHeight / 2),
+ des: 'scroll half a page up',
+ cat: 'Navigation'
+ },
+ 68: {
+ key: 'd',
+ fun: scrollPage(window.innerHeight / 2),
+ des: 'scroll half a page down',
+ cat: 'Navigation'
+ },
+ 71: {
+ key: 'g',
+ fun: scrollPageTo(-document.body.scrollHeight, 'top'),
+ des: 'scroll to the top of the page',
+ cat: 'Navigation'
+ },
+ 86: {
+ key: 'v',
+ fun: scrollPageTo(document.body.scrollHeight, 'bottom'),
+ des: 'scroll to the bottom of the page',
+ cat: 'Navigation'
+ },
+ 75: {
+ key: 'k',
+ fun: highlightResult('up'),
+ des: 'select previous search result',
+ cat: 'Results'
+ },
+ 74: {
+ key: 'j',
+ fun: highlightResult('down'),
+ des: 'select next search result',
+ cat: 'Results'
+ },
+ 80: {
+ key: 'p',
+ fun: pageButtonClick(0),
+ des: 'go to previous page',
+ cat: 'Results'
+ },
+ 78: {
+ key: 'n',
+ fun: pageButtonClick(1),
+ des: 'go to next page',
+ cat: 'Results'
+ },
+ 79: {
+ key: 'o',
+ fun: openResult(false),
+ des: 'open search result',
+ cat: 'Results'
+ },
+ 84: {
+ key: 't',
+ fun: openResult(true),
+ des: 'open the result in a new tab',
+ cat: 'Results'
+ },
+ 82: {
+ key: 'r',
+ fun: reloadPage,
+ des: 'reload page from the server',
+ cat: 'Control'
+ },
+ 72: {
+ key: 'h',
+ fun: toggleHelp,
+ des: 'toggle help window',
+ cat: 'Other'
+ }
+ };
+
+ searx.on(document, "keydown", function(e) {
+ // check for modifiers so we don't break browser's hotkeys
+ if (vimKeys.hasOwnProperty(e.keyCode) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
+ var tagName = e.target.tagName.toLowerCase();
+ if (e.keyCode === 27) {
+ if (tagName === 'input' || tagName === 'select' || tagName === 'textarea') {
+ vimKeys[e.keyCode].fun();
+ }
+ } else {
+ if (e.target === document.body || tagName === 'a' || tagName === 'button') {
+ e.preventDefault();
+ vimKeys[e.keyCode].fun();
+ }
+ }
+ }
+ });
+
+ function highlightResult(which) {
+ return function(noScroll) {
+ var current = document.querySelector('.result[data-vim-selected]'),
+ effectiveWhich = which;
+ if (current === null) {
+ // no selection : choose the first one
+ current = document.querySelector('.result');
+ if (current === null) {
+ // no first one : there are no results
+ return;
+ }
+ // replace up/down actions by selecting first one
+ if (which === "down" || which === "up") {
+ effectiveWhich = current;
+ }
+ }
+
+ var next, results = document.querySelectorAll('.result');
+
+ if (typeof effectiveWhich !== 'string') {
+ next = effectiveWhich;
+ } else {
+ switch (effectiveWhich) {
+ case 'visible':
+ var top = document.documentElement.scrollTop || document.body.scrollTop;
+ var bot = top + document.documentElement.clientHeight;
+
+ for (var i = 0; i < results.length; i++) {
+ next = results[i];
+ var etop = next.offsetTop;
+ var ebot = etop + next.clientHeight;
+
+ if ((ebot <= bot) && (etop > top)) {
+ break;
+ }
+ }
+ break;
+ case 'down':
+ next = current.nextElementSibling;
+ if (next === null) {
+ next = results[0];
+ }
+ break;
+ case 'up':
+ next = current.previousElementSibling;
+ if (next === null) {
+ next = results[results.length - 1];
+ }
+ break;
+ case 'bottom':
+ next = results[results.length - 1];
+ break;
+ case 'top':
+ /* falls through */
+ default:
+ next = results[0];
+ }
+ }
+
+ if (next) {
+ current.removeAttribute('data-vim-selected');
+ next.setAttribute('data-vim-selected', 'true');
+ var link = next.querySelector('h3 a') || next.querySelector('a');
+ if (link !== null) {
+ link.focus();
+ }
+ if (!noScroll) {
+ scrollPageToSelected();
+ }
+ }
+ };
+ }
+
+ function reloadPage() {
+ document.location.reload(true);
+ }
+
+ function removeFocus() {
+ if (document.activeElement) {
+ document.activeElement.blur();
+ }
+ }
+
+ function pageButtonClick(num) {
+ return function() {
+ var buttons = $('div#pagination button[type="submit"]');
+ if (buttons.length !== 2) {
+ console.log('page navigation with this theme is not supported');
+ return;
+ }
+ if (num >= 0 && num < buttons.length) {
+ buttons[num].click();
+ } else {
+ console.log('pageButtonClick(): invalid argument');
+ }
+ };
+ }
+
+ function scrollPageToSelected() {
+ var sel = document.querySelector('.result[data-vim-selected]');
+ if (sel === null) {
+ return;
+ }
+ var wtop = document.documentElement.scrollTop || document.body.scrollTop,
+ wheight = document.documentElement.clientHeight,
+ etop = sel.offsetTop,
+ ebot = etop + sel.clientHeight,
+ offset = 120;
+ // first element ?
+ if ((sel.previousElementSibling === null) && (ebot < wheight)) {
+ // set to the top of page if the first element
+ // is fully included in the viewport
+ window.scroll(window.scrollX, 0);
+ return;
+ }
+ if (wtop > (etop - offset)) {
+ window.scroll(window.scrollX, etop - offset);
+ } else {
+ var wbot = wtop + wheight;
+ if (wbot < (ebot + offset)) {
+ window.scroll(window.scrollX, ebot - wheight + offset);
+ }
+ }
+ }
+
+ function scrollPage(amount) {
+ return function() {
+ window.scrollBy(0, amount);
+ highlightResult('visible')();
+ };
+ }
+
+ function scrollPageTo(position, nav) {
+ return function() {
+ window.scrollTo(0, position);
+ highlightResult(nav)();
+ };
+ }
+
+ function searchInputFocus() {
+ window.scrollTo(0, 0);
+ document.querySelector('#q').focus();
+ }
+
+ function openResult(newTab) {
+ return function() {
+ var link = document.querySelector('.result[data-vim-selected] h3 a');
+ if (link !== null) {
+ var url = link.getAttribute('href');
+ if (newTab) {
+ window.open(url);
+ } else {
+ window.location.href = url;
+ }
+ }
+ };
+ }
+
+ function initHelpContent(divElement) {
+ var categories = {};
+
+ for (var k in vimKeys) {
+ var key = vimKeys[k];
+ categories[key.cat] = categories[key.cat] || [];
+ categories[key.cat].push(key);
+ }
+
+ var sorted = Object.keys(categories).sort(function(a, b) {
+ return categories[b].length - categories[a].length;
+ });
+
+ if (sorted.length === 0) {
+ return;
+ }
+
+ var html = '<a href="#" class="close" aria-label="close" title="close">×</a>';
+ html += '<h3>How to navigate searx with Vim-like hotkeys</h3>';
+ html += '<table>';
+
+ for (var i = 0; i < sorted.length; i++) {
+ var cat = categories[sorted[i]];
+
+ var lastCategory = i === (sorted.length - 1);
+ var first = i % 2 === 0;
+
+ if (first) {
+ html += '<tr>';
+ }
+ html += '<td>';
+
+ html += '<h4>' + cat[0].cat + '</h4>';
+ html += '<ul class="list-unstyled">';
+
+ for (var cj in cat) {
+ html += '<li><kbd>' + cat[cj].key + '</kbd> ' + cat[cj].des + '</li>';
+ }
+
+ html += '</ul>';
+ html += '</td>'; // col-sm-*
+
+ if (!first || lastCategory) {
+ html += '</tr>'; // row
+ }
+ }
+
+ html += '</table>';
+
+ divElement.innerHTML = html;
+ }
+
+ function toggleHelp() {
+ var helpPanel = document.querySelector('#vim-hotkeys-help');
+ console.log(helpPanel);
+ if (helpPanel === undefined || helpPanel === null) {
+ // first call
+ helpPanel = document.createElement('div');
+ helpPanel.id = 'vim-hotkeys-help';
+ helpPanel.className='dialog-modal';
+ helpPanel.style='width: 40%';
+ initHelpContent(helpPanel);
+ var body = document.getElementsByTagName('body')[0];
+ body.appendChild(helpPanel);
+ } else {
+ // togggle hidden
+ helpPanel.classList.toggle('invisible');
+ return;
+ }
+
+ }
+
+});
diff --git a/searx/static/themes/simple/src/js/main/searx_mapresult.js b/searx/static/themes/simple/src/js/main/searx_mapresult.js
new file mode 100644
index 000000000..2ccdbd1c7
--- /dev/null
+++ b/searx/static/themes/simple/src/js/main/searx_mapresult.js
@@ -0,0 +1,89 @@
+/**
+* searx is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* searx is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
+*
+* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
+*/
+(function (w, d, searx) {
+ 'use strict';
+
+ searx.ready(function () {
+ searx.on('.searx_init_map', 'click', function(event) {
+ // no more request
+ this.classList.remove("searx_init_map");
+
+ //
+ var leaflet_target = this.dataset.leafletTarget;
+ var map_lon = parseFloat(this.dataset.mapLon);
+ var map_lat = parseFloat(this.dataset.mapLat);
+ var map_zoom = parseFloat(this.dataset.mapZoom);
+ var map_boundingbox = JSON.parse(this.dataset.mapBoundingbox);
+ var map_geojson = JSON.parse(this.dataset.mapGeojson);
+
+ searx.loadStyle('leaflet/leaflet.css');
+ searx.loadScript('leaflet/leaflet.js', function() {
+ var map_bounds = null;
+ if(map_boundingbox) {
+ var southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
+ var northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
+ map_bounds = L.latLngBounds(southWest, northEast);
+ }
+
+ // init map
+ var map = L.map(leaflet_target);
+ // create the tile layer with correct attribution
+ var osmMapnikUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
+ var osmMapnikAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
+ var osmMapnik = new L.TileLayer(osmMapnikUrl, {minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib});
+ var osmWikimediaUrl='https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png';
+ var osmWikimediaAttrib = 'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
+ var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {minZoom: 1, maxZoom: 19, attribution: osmWikimediaAttrib});
+ // init map view
+ if(map_bounds) {
+ // TODO hack: https://github.com/Leaflet/Leaflet/issues/2021
+ // Still useful ?
+ setTimeout(function () {
+ map.fitBounds(map_bounds, {
+ maxZoom:17
+ });
+ }, 0);
+ } else if (map_lon && map_lat) {
+ if(map_zoom) {
+ map.setView(new L.latLng(map_lat, map_lon),map_zoom);
+ } else {
+ map.setView(new L.latLng(map_lat, map_lon),8);
+ }
+ }
+
+ map.addLayer(osmMapnik);
+
+ var baseLayers = {
+ "OSM Mapnik": osmMapnik/*,
+ "OSM Wikimedia": osmWikimedia*/
+ };
+
+ L.control.layers(baseLayers).addTo(map);
+
+ if(map_geojson) {
+ L.geoJson(map_geojson).addTo(map);
+ } /*else if(map_bounds) {
+ L.rectangle(map_bounds, {color: "#ff7800", weight: 3, fill:false}).addTo(map);
+ }*/
+ });
+
+ // this event occour only once per element
+ event.preventDefault();
+ });
+ });
+})(window, document, window.searx);
diff --git a/searx/static/themes/simple/src/js/main/searx_results.js b/searx/static/themes/simple/src/js/main/searx_results.js
new file mode 100644
index 000000000..fe00efc90
--- /dev/null
+++ b/searx/static/themes/simple/src/js/main/searx_results.js
@@ -0,0 +1,63 @@
+/**
+* searx is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* searx is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
+*
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
+*/
+(function(w, d, searx) {
+ 'use strict';
+
+ searx.ready(function() {
+ searx.image_thumbnail_layout = new searx.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 10, 200);
+ searx.image_thumbnail_layout.watch();
+
+ searx.on('.btn-collapse', 'click', function(event) {
+ var btnLabelCollapsed = this.getAttribute('data-btn-text-collapsed');
+ var btnLabelNotCollapsed = this.getAttribute('data-btn-text-not-collapsed');
+ var target = this.getAttribute('data-target');
+ var targetElement = d.querySelector(target);
+ var html = this.innerHTML;
+ if (this.classList.contains('collapsed')) {
+ html = html.replace(btnLabelCollapsed, btnLabelNotCollapsed);
+ } else {
+ html = html.replace(btnLabelNotCollapsed, btnLabelCollapsed);
+ }
+ this.innerHTML = html;
+ this.classList.toggle('collapsed');
+ targetElement.classList.toggle('invisible');
+ });
+
+ searx.on('.media-loader', 'click', function(event) {
+ var target = this.getAttribute('data-target');
+ var iframe_load = d.querySelector(target + ' > iframe');
+ var srctest = iframe_load.getAttribute('src');
+ if (srctest === null || srctest === undefined || srctest === false) {
+ iframe_load.setAttribute('src', iframe_load.getAttribute('data-src'));
+ }
+ });
+
+ w.addEventListener('scroll', function() {
+ var e = d.getElementById('backToTop'),
+ scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
+ if (e !== null) {
+ if (scrollTop >= 200) {
+ e.style.opacity = 1;
+ } else {
+ e.style.opacity = 0;
+ }
+ }
+ });
+
+ });
+
+})(window, document, window.searx);
diff --git a/searx/static/themes/simple/src/js/main/searx_search.js b/searx/static/themes/simple/src/js/main/searx_search.js
new file mode 100644
index 000000000..0e498717c
--- /dev/null
+++ b/searx/static/themes/simple/src/js/main/searx_search.js
@@ -0,0 +1,121 @@
+/**
+* searx is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* searx is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
+*
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
+*/
+(function(w, d, searx) {
+ 'use strict';
+
+ var firstFocus = true, qinput_id = "q", qinput;
+
+ function placeCursorAtEnd(element) {
+ if (element.setSelectionRange) {
+ var len = element.value.length;
+ element.setSelectionRange(len, len);
+ }
+ }
+
+ function submitIfQuery() {
+ if (qinput.value.length > 0) {
+ var search = document.getElementById('search');
+ setTimeout(search.submit.bind(search), 0);
+ }
+ }
+
+ function createClearButton(qinput) {
+ var cs = document.getElementById('clear_search');
+ var updateClearButton = function() {
+ if (qinput.value.length === 0) {
+ cs.classList.add("empty");
+ } else {
+ cs.classList.remove("empty");
+ }
+ };
+
+ // update status, event listener
+ updateClearButton();
+ cs.addEventListener('click', function() {
+ qinput.value='';
+ qinput.focus();
+ updateClearButton();
+ });
+ qinput.addEventListener('keyup', updateClearButton, false);
+ }
+
+ searx.ready(function() {
+ qinput = d.getElementById(qinput_id);
+
+ function placeCursorAtEndOnce(e) {
+ if (firstFocus) {
+ placeCursorAtEnd(qinput);
+ firstFocus = false;
+ } else {
+ // e.preventDefault();
+ }
+ }
+
+ if (qinput !== null) {
+ // clear button
+ createClearButton(qinput);
+
+ // autocompleter
+ if (searx.autocompleter) {
+ searx.autocomplete = AutoComplete.call(w, {
+ Url: "./autocompleter",
+ EmptyMessage: searx.translations.no_item_found,
+ HttpMethod: searx.method,
+ HttpHeaders: {
+ "Content-type": "application/x-www-form-urlencoded",
+ "X-Requested-With": "XMLHttpRequest"
+ },
+ MinChars: 4,
+ Delay: 300,
+ }, "#" + qinput_id);
+
+ // hack, see : https://github.com/autocompletejs/autocomplete.js/issues/37
+ w.addEventListener('resize', function() {
+ var event = new CustomEvent("position");
+ qinput.dispatchEvent(event);
+ });
+ }
+
+ qinput.addEventListener('focus', placeCursorAtEndOnce, false);
+ qinput.focus();
+ }
+
+ // vanilla js version of search_on_category_select.js
+ if (qinput !== null && searx.search_on_category_select) {
+ d.querySelector('.help').className='invisible';
+
+ searx.on('#categories input', 'change', function(e) {
+ var i, categories = d.querySelectorAll('#categories input[type="checkbox"]');
+ for(i=0; i<categories.length; i++) {
+ if (categories[i] !== this && categories[i].checked) {
+ categories[i].click();
+ }
+ }
+ if (! this.checked) {
+ this.click();
+ }
+ submitIfQuery();
+ return false;
+ });
+
+ searx.on(d.getElementById('time_range'), 'change', submitIfQuery);
+ searx.on(d.getElementById('language'), 'change', submitIfQuery);
+ }
+
+ });
+
+})(window, document, window.searx);
diff --git a/searx/static/themes/simple/src/less/autocomplete.less b/searx/static/themes/simple/src/less/autocomplete.less
new file mode 100644
index 000000000..93f7df1ef
--- /dev/null
+++ b/searx/static/themes/simple/src/less/autocomplete.less
@@ -0,0 +1,69 @@
+/*! Autocomplete.js v2.6.3 | license MIT | (c) 2017, Baptiste Donaux | http://autocomplete-js.com */
+
+@background_color: white;
+
+.autocomplete {
+ position: absolute;
+ max-height: 0;
+ overflow-y: hidden;
+ text-align: left;
+
+ &:active, &:focus, &:hover {
+ background-color: @background_color;
+ }
+
+ &:empty {
+ display: none;
+ }
+
+ > ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ > li {
+ cursor: pointer;
+ padding: 5px 0 5px 10px;
+
+ &.active, &:active, &:focus {
+ background-color: @color-base;
+
+ a:active, a:focus, a:hover {
+ text-decoration: none;
+ }
+ }
+
+ &.locked {
+ cursor: inherit;
+ }
+ }
+ }
+
+ &.open {
+ display: block;
+ background-color: @background_color;
+ border: 1px solid @color-base;
+ max-height: 500px;
+ overflow-y: auto;
+ z-index:100;
+
+ &:empty {
+ display: none;
+ }
+ }
+}
+
+
+@media screen and (max-width: @results-width) {
+
+ .autocomplete {
+ bottom: 0;
+ }
+
+ .autocomplete > ul > li {
+ padding: 7px 0 7px 10px;
+ border-bottom: 1px solid @color-result-top-border;
+ text-align: left;
+ }
+
+}
diff --git a/searx/static/themes/simple/src/less/code.less b/searx/static/themes/simple/src/less/code.less
new file mode 100644
index 000000000..b732103fb
--- /dev/null
+++ b/searx/static/themes/simple/src/less/code.less
@@ -0,0 +1,8 @@
+.code-highlight pre {
+ overflow: auto;
+ background-color: inherit;
+ color: inherit;
+ border: inherit;
+}
+
+@import "pygments.less";
diff --git a/searx/static/themes/simple/src/less/definitions.less b/searx/static/themes/simple/src/less/definitions.less
new file mode 100644
index 000000000..c1465a579
--- /dev/null
+++ b/searx/static/themes/simple/src/less/definitions.less
@@ -0,0 +1,138 @@
+/*
+ * searx, A privacy-respecting, hackable metasearch engine
+ *
+ * To change the colors of the site, simple edit this variables
+ */
+
+/// Basic Colors
+
+@color-base: #3498DB;
+@color-base-dark: #084999;
+@color-base-light: #ECF0F1;
+@color-highlight: #094089;
+@color-black: #000000;
+
+///
+@color-error: #db3434;
+@color-error-background: lighten(@color-error, 40%);
+
+@color-warning: #dbba34;
+@color-warning-background: lighten(@color-warning, 40%);
+
+@color-success: #42db34;
+@color-success-background: lighten(@color-success, 40%);
+
+/// General
+
+@color-font: #444;
+@color-font-light: #888;
+
+@color-red: #25a55b;
+
+@color-url-font: #29314d;
+@color-url-visited-font: #684898;
+@results-width: 50em;
+@search-width: 40em;
+
+//
+@color-a-font: @color-base;
+@color-a-font-hover: @color-base;
+
+
+/// Start-Screen
+
+
+
+/// Search-Input
+
+@color-search-border: @color-base;
+@color-search-background: #FFF;
+@color-search-font: #222;
+
+/// Autocompleter
+
+@color-autocompleter-choices-background: #FFF;
+@color-autocompleter-choices-border: @color-base;
+@color-autocompleter-choices-border-left-right: @color-base;
+@color-autocompleter-choices-border-bottom: @color-base;
+
+@color-autocompleter-choices-font: #444;
+
+/// Answers
+@color-answers-border: @color-base-dark;
+
+// Selected
+@color-autocompleter-selected-background: #444;
+@color-autocompleter-selected-font: #FFF;
+@color-autocompleter-selected-queried-font: #9FCFFF;
+
+/// Categories
+
+@color-categories-item-selected: @color-base;
+@color-categories-item-selected-font: #FFF;
+
+@color-categories-item-border-selected: @color-base-dark;
+@color-categories-item-border-unselected: #E8E7E6;
+@color-categories-item-border-unselected-hover: @color-base;
+
+
+/// Results
+
+@color-suggestions-button-background: @color-base;
+@color-suggestions-button-font: #FFF;
+
+@color-download-button-background: @color-base;
+@color-download-button-font: #FFF;
+
+@color-result-search-background: @color-base-light;
+
+@color-result-definition-border: gray;
+@color-result-torrent-border: lightgray;
+@color-result-top-border: #E8E7E6;
+
+// Link to result
+@color-result-link-font: @color-base-dark;
+@color-result-link-visited-font: @color-url-visited-font;
+
+// Url to result
+@color-result-url-font: @color-red;
+
+// Publish Date
+@color-result-publishdate-font: @color-font-light;
+
+// Images
+@color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
+@color-result-image-span-font: #FFF;
+
+// Search-URL
+@color-result-search-url-border: #888;
+@color-result-search-url-font: #444;
+
+
+/// Settings
+
+@color-settings-fieldset: @color-base;
+@color-settings-table-striped: #dbdbdb;
+@color-settings-tr-hover: #ececec;
+
+// Labels
+@color-settings-label-allowed-background: #E74C3C;
+@color-settings-label-allowed-font: #FFF;
+
+@color-settings-label-deny-background: #2ECC71;
+@color-settings-label-deny-font: @color-font;
+
+@color-settings-return-background: @color-base;
+@color-settings-return-font: #FFF;
+
+/// Other
+
+@color-engines-font: @color-font-light;
+@color-percentage-div-background: #444;
+
+/// Load fonts from this directory.
+@icon-font-path: "../../../fonts/";
+//** File name for all font files.
+@icon-font-name: "glyphicons-halflings-regular";
+//** Element ID within SVG icon file.
+@icon-font-svg-id: "glyphicons_halflingsregular";
diff --git a/searx/static/themes/simple/src/less/index.less b/searx/static/themes/simple/src/less/index.less
new file mode 100644
index 000000000..e1efdac90
--- /dev/null
+++ b/searx/static/themes/simple/src/less/index.less
@@ -0,0 +1,43 @@
+.index {
+
+ text-align: center;
+
+ .title {
+ background: url('../img/searx.png') no-repeat;
+ width: 100%;
+ min-height: 80px;
+ background-position: center;
+ }
+
+ h1 {
+ font-size: 5em;
+ visibility: hidden;
+ }
+
+ #search {
+ margin: 0 auto;
+ background: inherit;
+ border: inherit;
+ }
+
+ .search_filters {
+ display: block;
+ margin: 1em 0;
+ }
+
+ .category label {
+ padding: 6px 10px;
+ border-bottom: initial !important;
+ }
+
+}
+
+@media screen and (max-width: 75em) {
+
+ div.title {
+ h1 {
+ font-size: 1em;
+ }
+ }
+
+}
diff --git a/searx/static/themes/simple/src/less/ion.less b/searx/static/themes/simple/src/less/ion.less
new file mode 100644
index 000000000..c9e715591
--- /dev/null
+++ b/searx/static/themes/simple/src/less/ion.less
@@ -0,0 +1,181 @@
+// Generated by grunt-webfont
+
+
+@font-face {
+ font-family:"ion";
+ src:url("../fonts/ion.eot?ce7a0ead692560b4405a96d5b8471f51");
+ src:url("../fonts/ion.eot?#iefix") format("embedded-opentype"),
+ url("../fonts/ion.woff2?ce7a0ead692560b4405a96d5b8471f51") format("woff2"),
+ url("../fonts/ion.woff?ce7a0ead692560b4405a96d5b8471f51") format("woff"),
+ url("../fonts/ion.ttf?ce7a0ead692560b4405a96d5b8471f51") format("truetype"),
+ url("../fonts/ion.svg?ce7a0ead692560b4405a96d5b8471f51#ion") format("svg");
+ font-weight:normal;
+ font-style:normal;
+}
+
+.ion-icon {
+ &:before {
+ font-family:"ion";
+ }
+ display:inline-block;
+ vertical-align:middle;
+ line-height:1;
+ font-weight:normal;
+ font-style:normal;
+ speak:none;
+ text-decoration:inherit;
+ text-transform:none;
+ text-rendering:auto;
+ -webkit-font-smoothing:antialiased;
+ -moz-osx-font-smoothing:grayscale;
+}
+
+
+// Icons
+
+.ion-navicon-round {
+ &:before {
+ content:"\f101";
+ }
+}
+
+
+.ion-search {
+ &:before {
+ content:"\f102";
+ }
+}
+
+
+.ion-play {
+ &:before {
+ content:"\f103";
+ }
+}
+
+
+.ion-link {
+ &:before {
+ content:"\f104";
+ }
+}
+
+
+.ion-chevron-up {
+ &:before {
+ content:"\f105";
+ }
+}
+
+
+.ion-chevron-left {
+ &:before {
+ content:"\f106";
+ }
+}
+
+
+.ion-chevron-right {
+ &:before {
+ content:"\f107";
+ }
+}
+
+
+.ion-arrow-down-a {
+ &:before {
+ content:"\f108";
+ }
+}
+
+
+.ion-arrow-up-a {
+ &:before {
+ content:"\f109";
+ }
+}
+
+
+.ion-arrow-swap {
+ &:before {
+ content:"\f10a";
+ }
+}
+
+
+.ion-arrow-dropdown {
+ &:before {
+ content:"\f10b";
+ }
+}
+
+
+.ion-globe {
+ &:before {
+ content:"\f10c";
+ }
+}
+
+
+.ion-time {
+ &:before {
+ content:"\f10d";
+ }
+}
+
+
+.ion-location {
+ &:before {
+ content:"\f10e";
+ }
+}
+
+
+.ion-warning {
+ &:before {
+ content:"\f10f";
+ }
+}
+
+
+.ion-error {
+ &:before {
+ content:"\f110";
+ }
+}
+
+
+.ion-film-outline {
+ &:before {
+ content:"\f111";
+ }
+}
+
+
+.ion-music-note {
+ &:before {
+ content:"\f112";
+ }
+}
+
+
+.ion-more-vertical {
+ &:before {
+ content:"\f113";
+ }
+}
+
+
+.ion-magnet {
+ &:before {
+ content:"\f114";
+ }
+}
+
+
+.ion-close {
+ &:before {
+ content:"\f115";
+ }
+}
+
diff --git a/searx/static/themes/simple/src/less/mixins.less b/searx/static/themes/simple/src/less/mixins.less
new file mode 100644
index 000000000..b3aa4e13d
--- /dev/null
+++ b/searx/static/themes/simple/src/less/mixins.less
@@ -0,0 +1,62 @@
+/*
+* searx, A privacy-respecting, hackable metasearch engine
+*/
+
+// Mixins
+.text-size-adjust (@property: 100%) {
+ -webkit-text-size-adjust: @property;
+ -ms-text-size-adjust: @property;
+ -moz-text-size-adjust: @property;
+ text-size-adjust: @property;
+}
+
+.rounded-corners (@radius: 4px) {
+ -webkit-border-radius: @radius;
+ -moz-border-radius: @radius;
+ border-radius: @radius;
+}
+
+// disable user selection
+.disable-user-select () {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+// select all on focus
+.select-all-on-focus() {
+ -webkit-user-select: all;
+ -moz-user-select: all;
+ -ms-user-select: element;
+ user-select: all;
+}
+
+// see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Advanced_layouts_with_flexbox
+.flexbox() {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+}
+
+.inline-flex() {
+ display: -webkit-inline-box;
+ display: -moz-inline-box;
+ display: -webkit-inline-flex;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+}
+
+.flex-direction-row() {
+ -webkit-box-direction: normal;
+ -webkit-box-orient: horizontal;
+ -moz-box-direction: normal;
+ -moz-box-orient: horizontal;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+}
diff --git a/searx/static/themes/simple/src/less/normalize.less b/searx/static/themes/simple/src/less/normalize.less
new file mode 100644
index 000000000..47b010e47
--- /dev/null
+++ b/searx/static/themes/simple/src/less/normalize.less
@@ -0,0 +1,341 @@
+/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
+
+/* Document
+ ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Misc
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
diff --git a/searx/static/themes/simple/src/less/preferences.less b/searx/static/themes/simple/src/less/preferences.less
new file mode 100644
index 000000000..e1e88b51f
--- /dev/null
+++ b/searx/static/themes/simple/src/less/preferences.less
@@ -0,0 +1,103 @@
+#main_preferences {
+ form {
+ width: 100%;
+ }
+
+ fieldset {
+ margin: 8px;
+ border: none;
+ }
+
+ legend {
+ margin: 0;
+ padding: 5px 0 0 0;
+ display: block;
+ float:left;
+ width: 300px;
+ }
+
+ .value {
+ margin: 0;
+ padding: 0;
+ float:left;
+ width: 15em;
+ }
+
+ .description {
+ margin: 0;
+ padding: 5px 0 0 0;
+ float:left;
+ width: 50%;
+ color: darken(#dcdcdc, 30%);
+ font-size: 90%;
+ }
+
+ select {
+ width: 200px;
+ font-size: inherit !important;
+ }
+
+ table {
+ border-collapse: collapse;
+ }
+
+ table td {
+ text-align: center;
+ }
+
+ table.cookies {
+ width: auto;
+
+ th, td {
+ text-align: left;
+ padding: 0.25em;
+ }
+
+ th:first-child, td:first-child {
+ padding-right: 4em;
+ }
+
+ &>tbody>tr:nth-child(even)>th,
+ &>tbody>tr:nth-child(even)>td {
+ background-color: @color-settings-tr-hover;
+ }
+ }
+
+ .name, .shortcut {
+ text-align: left;
+ }
+
+ .preferences_back {
+ background: none repeat scroll 0 0 @color-settings-return-background;
+ color: white;
+ border: 0 none;
+ .rounded-corners;
+ cursor: pointer;
+ display: inline-block;
+ margin: 2px 4px;
+ padding: 0.5em;
+
+ a {
+ display: block;
+ color: @color-settings-return-font;
+ }
+
+ a::first-letter {
+ text-transform: uppercase;
+ }
+ }
+
+
+ div.selectable_url {
+ pre {
+ width: 100%;
+ }
+ }
+
+}
+
+@media screen and (max-width: 75em) {
+ .preferences_back {
+ clear: both;
+ }
+}
diff --git a/searx/static/themes/simple/src/less/pygments.less b/searx/static/themes/simple/src/less/pygments.less
new file mode 100644
index 000000000..e5ec9b8d9
--- /dev/null
+++ b/searx/static/themes/simple/src/less/pygments.less
@@ -0,0 +1,99 @@
+/*
+ this file is generated automatically by searx_extra/update/update_pygments.py
+ using pygments version 2.8.1
+*/
+
+.code-highlight .linenos {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+
+ &::selection {
+ background: transparent; /* WebKit/Blink Browsers */
+ }
+ &::-moz-selection {
+ background: transparent; /* Gecko Browsers */
+ }
+
+ margin-right: 8px;
+ text-align: right;
+}
+
+.code-highlight pre { line-height: 125%; }
+.code-highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+.code-highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+.code-highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.code-highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.code-highlight .hll { background-color: #ffffcc }
+.code-highlight { background: #f8f8f8; }
+.code-highlight .c { color: #408080; font-style: italic } /* Comment */
+.code-highlight .err { border: 1px solid #FF0000 } /* Error */
+.code-highlight .k { color: #008000; font-weight: bold } /* Keyword */
+.code-highlight .o { color: #666666 } /* Operator */
+.code-highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
+.code-highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.code-highlight .cp { color: #BC7A00 } /* Comment.Preproc */
+.code-highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
+.code-highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
+.code-highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
+.code-highlight .gd { color: #A00000 } /* Generic.Deleted */
+.code-highlight .ge { font-style: italic } /* Generic.Emph */
+.code-highlight .gr { color: #FF0000 } /* Generic.Error */
+.code-highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.code-highlight .gi { color: #00A000 } /* Generic.Inserted */
+.code-highlight .go { color: #888888 } /* Generic.Output */
+.code-highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.code-highlight .gs { font-weight: bold } /* Generic.Strong */
+.code-highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.code-highlight .gt { color: #0044DD } /* Generic.Traceback */
+.code-highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.code-highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.code-highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.code-highlight .kp { color: #008000 } /* Keyword.Pseudo */
+.code-highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.code-highlight .kt { color: #B00040 } /* Keyword.Type */
+.code-highlight .m { color: #666666 } /* Literal.Number */
+.code-highlight .s { color: #BA2121 } /* Literal.String */
+.code-highlight .na { color: #7D9029 } /* Name.Attribute */
+.code-highlight .nb { color: #008000 } /* Name.Builtin */
+.code-highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.code-highlight .no { color: #880000 } /* Name.Constant */
+.code-highlight .nd { color: #AA22FF } /* Name.Decorator */
+.code-highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
+.code-highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.code-highlight .nf { color: #0000FF } /* Name.Function */
+.code-highlight .nl { color: #A0A000 } /* Name.Label */
+.code-highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.code-highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.code-highlight .nv { color: #19177C } /* Name.Variable */
+.code-highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.code-highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.code-highlight .mb { color: #666666 } /* Literal.Number.Bin */
+.code-highlight .mf { color: #666666 } /* Literal.Number.Float */
+.code-highlight .mh { color: #666666 } /* Literal.Number.Hex */
+.code-highlight .mi { color: #666666 } /* Literal.Number.Integer */
+.code-highlight .mo { color: #666666 } /* Literal.Number.Oct */
+.code-highlight .sa { color: #BA2121 } /* Literal.String.Affix */
+.code-highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
+.code-highlight .sc { color: #BA2121 } /* Literal.String.Char */
+.code-highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.code-highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.code-highlight .s2 { color: #BA2121 } /* Literal.String.Double */
+.code-highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.code-highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.code-highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.code-highlight .sx { color: #008000 } /* Literal.String.Other */
+.code-highlight .sr { color: #BB6688 } /* Literal.String.Regex */
+.code-highlight .s1 { color: #BA2121 } /* Literal.String.Single */
+.code-highlight .ss { color: #19177C } /* Literal.String.Symbol */
+.code-highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.code-highlight .fm { color: #0000FF } /* Name.Function.Magic */
+.code-highlight .vc { color: #19177C } /* Name.Variable.Class */
+.code-highlight .vg { color: #19177C } /* Name.Variable.Global */
+.code-highlight .vi { color: #19177C } /* Name.Variable.Instance */
+.code-highlight .vm { color: #19177C } /* Name.Variable.Magic */
+.code-highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
diff --git a/searx/static/themes/simple/src/less/search.less b/searx/static/themes/simple/src/less/search.less
new file mode 100644
index 000000000..dbcfc932e
--- /dev/null
+++ b/searx/static/themes/simple/src/less/search.less
@@ -0,0 +1,264 @@
+/*
+* searx, A privacy-respecting, hackable metasearch engine
+*/
+
+#search {
+ padding: 0 2em;
+ margin: 0;
+ background: #f7f7f7;
+ border-bottom: 1px solid #d7d7d7;
+}
+
+#search_wrapper {
+ padding: 10px 0;
+}
+
+.search_box {
+ margin: 0 12px 0 0;
+ display: inline-flex;
+ flex-direction: row;
+
+ white-space: nowrap;
+ /*
+ &:has(q:focus) {
+ box-shadow: 0px 0px 5px #CCC;
+}
+*/
+}
+
+#clear_search {
+ display: block;
+ border-collapse: separate;
+ box-sizing: border-box;
+ width: 1.8em;
+
+ margin: 0;
+ padding: 2px;
+ height: 2.2em;
+ background: none repeat scroll 0 0 @color-search-background;
+ border-top: 1px solid @color-search-border;
+ border-bottom: 1px solid @color-search-border;
+ border-right: none;
+ border-left: none;
+ border-radius: 0px;
+ outline: none;
+ color: @color-search-font;
+ font-size: 16px;
+ z-index: 10000;
+
+ &:hover {
+ color: @color-search-border;
+ }
+
+ &.empty * {
+ display: none;
+ }
+}
+
+#q::-ms-clear, #q::-webkit-search-cancel-button {
+ display: none;
+}
+
+#q, #send_search {
+ display: block !important;
+ border-collapse: separate;
+ box-sizing: border-box;
+
+ margin: 0;
+ padding: 2px;
+ height: 2.2em;
+ background: none repeat scroll 0 0 @color-search-background;
+ border: 1px solid @color-search-border;
+ border-radius: 0px;
+ outline: none;
+ color: @color-search-font;
+ font-size: 16px;
+ z-index: 2;
+}
+
+#q {
+ outline: medium none;
+ padding-left: 8px;
+ padding-right: 0px !important;
+ border-right: none;
+ width: @search-width;
+}
+
+#send_search {
+ border-left: none;
+ width: 2.2em;
+
+ &:hover {
+ cursor: pointer;
+ background-color: @color-search-border;
+ color: @color-base-light;
+ }
+}
+
+.no-js #send_search {
+ width: auto !important;
+}
+
+.search_filters {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+@media screen and (max-width: 75em) {
+
+ #categories {
+ font-size: 90%;
+ clear: both;
+
+ .checkbox_container {
+ margin-top: 2px;
+ margin: auto;
+ }
+ }
+
+ html.touch {
+ #main_index, #main_results {
+
+ #categories_container {
+ width: 1000px;
+ width: -moz-max-content;
+ width: -webkit-max-content;
+ width: max-content;
+
+ .category {
+ display: inline-block;
+ width: auto;
+ }
+ }
+
+ #categories {
+ width: 100%;
+ margin: 0;
+ text-align: left;
+ overflow-x: scroll;
+ overflow-y: hidden;
+ -webkit-overflow-scrolling: touch;
+ }
+ }
+ }
+
+}
+
+@media screen and (max-width: @results-width) {
+
+ #search {
+ width: 100%;
+ margin: 0;
+ padding: 0.1em 0 0 0;
+ }
+
+ #search_wrapper {
+ width: 100%;
+ margin: 0 0 0.7em 0;
+ padding: 0;
+ }
+
+ .search_box {
+ // hack, should bew 100% ?
+ width: 99%;
+ margin: 0.1em;
+ padding: 0 0.1em 0 0;
+ display: flex;
+ flex-direction: row;
+ }
+
+ #q {
+ width: auto !important;
+ flex: 1;
+ }
+
+ .search_filters {
+ display: block;
+ margin: 0.5em;
+ }
+
+ .language, .time_range {
+ width: 45%;
+ }
+
+ .category {
+ display: block;
+ width: 90%;
+
+ label {
+ border-bottom: 0;
+ }
+ }
+
+}
+
+#categories {
+ margin: 0 10px 0 0;
+ .disable-user-select;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ }
+}
+
+.category {
+ display: inline-block;
+ position: relative;
+ margin: 0 3px;
+ padding: 0px;
+
+ input {
+ display: none;
+ }
+
+ label {
+ cursor: pointer;
+ padding: 4px 10px;
+ margin: 0;
+ display: block;
+ text-transform: capitalize;
+ font-size: 0.9em;
+ border-bottom: 2px solid transparent;
+ .disable-user-select;
+ }
+
+ input[type="checkbox"]:focus + label {
+ box-shadow: 0px 0px 8px #3498DB;
+ }
+
+ /*label:hover {
+ border-bottom: 2px solid @color-categories-item-border-unselected-hover;
+ }*/
+
+ input[type="checkbox"]:checked + label {
+ background: @color-categories-item-selected;
+ color: @color-categories-item-selected-font;
+ border-bottom: 2px solid @color-categories-item-border-selected;
+ }
+}
+
+#categories_container {
+
+ position: relative;
+
+ .help {
+ position: absolute;
+ width: 100%;
+ bottom: -20px;
+ overflow: hidden;
+
+ opacity: 0;
+ transition: opacity 1s ease;
+
+ font-size: 0.8em;
+ text-position: center;
+ background: white;
+ }
+
+ &:hover .help {
+ opacity: 0.8;
+ transition: opacity 1s ease;
+ }
+
+}
diff --git a/searx/static/themes/simple/src/less/style-rtl.less b/searx/static/themes/simple/src/less/style-rtl.less
new file mode 100644
index 000000000..2b68bcfde
--- /dev/null
+++ b/searx/static/themes/simple/src/less/style-rtl.less
@@ -0,0 +1,6 @@
+@import "style.less";
+
+#search_submit {
+ left: 1px;
+ right:auto;
+}
diff --git a/searx/static/themes/simple/src/less/style.less b/searx/static/themes/simple/src/less/style.less
new file mode 100644
index 000000000..61c0a93de
--- /dev/null
+++ b/searx/static/themes/simple/src/less/style.less
@@ -0,0 +1,762 @@
+/*
+* searx, A privacy-respecting, hackable metasearch engine
+*
+* To convert "style.less" to "style.css" run: $make styles
+*/
+
+@stacked-bar-chart: rgb(0, 0, 0);
+
+@import "../../__common__/less/new_issue.less";
+@import "../../__common__/less/stats.less";
+
+@import "normalize.less";
+
+@import "definitions.less";
+
+@import "mixins.less";
+
+@import "code.less";
+
+@import "toolkit.less";
+
+@import "autocomplete.less";
+
+// ion-icon
+@import "ion.less";
+
+.ion-icon-big {
+ .ion-icon;
+ font-size: 149%;
+}
+
+// for index.html template
+@import "index.less";
+
+// for preferences.html template
+@import "preferences.less";
+
+// Search-Field
+@import "search.less";
+
+// Main LESS-Code
+html {
+ font-family: arial, sans-serif;
+ font-size: 0.9em;
+ .text-size-adjust;
+ color: @color-font;
+ padding: 0;
+ margin: 0;
+}
+
+body, main {
+ padding: 0;
+ margin: 0;
+}
+
+main {
+ width: 100%;
+ // position: absolute;
+}
+
+footer {
+ // position:absolute;
+ bottom:0;
+ width:100%;
+ height:50px;
+}
+
+#main_preferences, #main_about, #main_stats {
+ margin: 3em;
+ width: auto;
+}
+
+footer {
+ bottom: 0;
+ height: 3em;
+ margin: 1em 0;
+ padding: 1em 0;
+ clear: both;
+ width: 100%;
+ text-align: center;
+
+ p {
+ font-size: 0.9em;
+ }
+}
+
+#main_preferences h1, #main_stats h1 {
+ background: url('../img/searx.png') no-repeat;
+ background-size: auto 75%;
+ min-height: 40px;
+ margin: 0 auto;
+
+ span {
+ visibility: hidden;
+ }
+}
+
+input[type="submit"], #results button[type="submit"] {
+ padding: 0.5rem;
+ margin: 2px 4px;
+ display: inline-block;
+ background: @color-download-button-background;
+ color: @color-download-button-font;
+ .rounded-corners;
+ border: 0;
+ cursor: pointer;
+}
+
+a {
+ text-decoration: none;
+ color: @color-url-font;
+
+ &:visited {
+ color: @color-url-visited-font;
+
+ .highlight {
+ color: @color-url-visited-font;
+ }
+ }
+}
+
+article[data-vim-selected] {
+ background: #f7f7f7;
+}
+
+article[data-vim-selected]::before {
+ position: absolute;
+ left: 1em;
+ padding: 2px;
+ content: ">";
+ font-weight: bold;
+ color: @color-base;
+}
+
+article.result-images[data-vim-selected] {
+ background: @color-base;
+}
+
+article.result-images[data-vim-selected]::before {
+ display: none;
+ content: "";
+}
+
+.result {
+ margin: 19px 0 18px 0;
+ padding: 0;
+
+ h3 {
+ font-size: 1.1em;
+ word-wrap:break-word;
+ margin: 5px 0 1px 0;
+ padding: 0;
+ margin-bottom: 0;
+
+ a {
+ color: @color-result-link-font;
+ font-weight: normal;
+ font-size: 1.1em;
+
+ &:visited {
+ color: @color-result-link-visited-font;
+ }
+
+ &:focus, &:hover {
+ text-decoration: underline;
+ border: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ outline:none;
+ }
+ }
+ }
+
+ .cache_link, .proxyfied_link {
+ font-size: 0.9em !important;
+ }
+
+ .content, .stat, .altlink {
+ font-size: 0.9em;
+ margin: 0;
+ padding: 0;
+ max-width: 54em;
+ word-wrap:break-word;
+ line-height: 1.24;
+
+ .highlight {
+ color: @color-black;
+ background: inherit;
+ font-weight: bold;
+ }
+ }
+
+ .codelines {
+ .highlight {
+ color: inherit;
+ background: inherit;
+ font-weight: normal;
+ }
+ }
+
+ .url {
+ font-size: 0.9em;
+ margin: 0 0 3px 0;
+ padding: 0;
+ max-width: 54em;
+ word-wrap:break-word;
+ color: @color-result-url-font;
+ }
+
+ .published_date {
+ font-size: 0.8em;
+ color: @color-result-publishdate-font;
+ }
+
+ img {
+
+ &.thumbnail {
+ float: left;
+ padding: 0 5px 10px 0;
+ width: 20em;
+ min-width: 20em;
+ min-height: 8em;
+ // background: @color-base-light;
+ }
+
+ &.image {
+ float: left;
+ padding: 0 5px 10px 0;
+ width: 100px;
+ max-height: 100px;
+ object-fit: scale-down;
+ object-position: right top;
+ }
+
+ }
+
+ .break {
+ clear: both;
+ }
+
+}
+
+.category-social .image {
+ width: auto !important;
+ min-width: 48px;
+ min-height: 48px;
+ padding: 0 5px 25px 0 !important;
+}
+
+.result-videos .content {
+ overflow: hidden;
+}
+
+.engines {
+ float: right;
+ color: @color-engines-font;
+
+ span {
+ font-size: smaller;
+ margin: 0 0.5em 0 0;
+ }
+}
+
+.small_font {
+ font-size: 0.8em;
+}
+
+.highlight {
+ color: @color-highlight;
+ background: inherit;
+ font-weight: bold;
+}
+
+.result-images {
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ position: relative;
+ max-height: 200px;
+
+ img {
+ float: inherit;
+ margin: 0;
+ padding: 0;
+ border: none;
+ max-height: 200px;
+ background: @color-base-dark;
+ }
+
+ span a {
+ display: none;
+ color: @color-result-image-span-font;
+ }
+
+ &:hover span a {
+ display: block;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ padding: 4px;
+ margin: 0 0 4px 4px;
+ background-color: @color-result-image-span-background-hover;
+ font-size: 0.7em;
+ }
+}
+
+.result-map {
+
+ img.image {
+ float: right !important;
+ height: 100px !important;
+ width: auto !important;
+ }
+
+ table {
+ font-size: .9em;
+ width: auto;
+ border-collapse: separate;
+ border-spacing: 0 0.35rem;
+
+ th {
+ font-weight: inherit;
+ width: 17rem;
+ vertical-align: top;
+ text-align: left;
+ }
+
+ td {
+ vertical-align: top;
+ text-align: left;
+ }
+ }
+}
+
+.hidden {
+ display: none !important;
+}
+
+.torrent_result {
+ border-left: 10px solid @color-result-torrent-border;
+ padding-left: 3px;
+
+ p {
+ margin: 3px;
+ font-size: 0.8em;
+ }
+
+ a {
+ color: @color-result-link-font;
+
+ &:hover {
+ text-decoration: underline;
+ }
+
+ &:visited {
+ color: @color-result-link-visited-font;
+ }
+ }
+}
+
+#results {
+ margin: 2em 2em 20px 2em;
+ padding: 0;
+ width: @results-width;
+}
+
+#suggestions {
+
+ .wrapper {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: flex-end;
+
+ form {
+ display: inline-block;
+ flex: 1 1 50%;
+ }
+ }
+}
+
+#suggestions, #answers, #corrections {
+ max-width: @results-width;
+}
+
+#suggestions, #answers, #infoboxes, #corrections {
+
+ input {
+ padding: 0;
+ margin: 3px;
+ font-size: 0.9em;
+ display: inline-block;
+ background: transparent;
+ color: @color-result-search-url-font;
+ cursor: pointer;
+ }
+
+ input[type="submit"], .infobox .url a {
+ color: @color-result-link-font;
+ text-decoration: none;
+ font-size: 0.9rem;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+}
+
+#corrections {
+ display: flex;
+ flex-flow: row wrap;
+ margin: 1em 0;
+
+ h4, input[type="submit"] {
+ display: inline-block;
+ margin: 0 0.5em 0 0;
+ }
+
+ input[type="submit"]::after {
+ content: ", "
+ }
+
+}
+
+#suggestions .title, #search_url .title, #apis .title {
+ margin: 2em 0 0.5em 0;
+ color: @color-font;
+}
+
+#answers {
+ margin: 10px 8px 10px 8px;
+ border: 1px solid #ddd;
+ padding: 0.9em;
+ box-shadow: 0px 0px 5px #CCC;
+
+ h4 {
+ display: none;
+ }
+
+ .answer {
+ display: block;
+ font-size: 1.2em;
+ font-weight: bold;
+ }
+}
+
+#answers, #infoboxes {
+ form {
+ min-width: 210px;
+ }
+}
+
+#sidebar {
+ position: absolute;
+ top: 100px;
+ left: 57em;
+
+ margin: 0px 2px 5px 5px;
+ padding: 0px 2px 2px;
+ max-width: 25em;
+ word-wrap: break-word;
+
+ .infobox {
+ margin: 10px 0 10px;
+ border: 1px solid #ddd;
+ padding: 0.9em;
+ font-size: 0.9em;
+ box-shadow: 0px 0px 5px #CCC;
+
+ h2 {
+ margin: 0 0 .5em 0;
+ }
+
+ img {
+ max-width: 100%;
+ max-height: 12em;
+ display: block;
+ margin: 0;
+ padding: 0;
+ }
+
+ dl {
+ margin: 0.5em 0;
+ }
+
+ dt {
+ display: inline;
+ margin: 0.5em 0.25em 0.5em 0;
+ padding: 0;
+ font-weight: bold;
+ }
+
+ dd {
+ display: inline;
+ margin: 0.5em 0;
+ padding: 0;
+ }
+
+ input {
+ font-size: 1em;
+ }
+
+ br {
+ clear: both;
+ }
+
+ .attributes, .urls {
+ clear: both;
+ }
+
+ }
+}
+
+#search_url {
+ margin-top: 8px;
+
+ div.selectable_url {
+ pre {
+ width: 200em;
+ }
+ }
+}
+
+#linkto_preferences {
+ position: absolute;
+ right: 10px;
+ top: 0.9em;
+ padding: 0;
+ border: 0;
+ display: block;
+
+ font-size: 1.2em;
+ color: @color-search-font;
+
+ a:link *, a:hover *, a:visited *, a:active * {
+ color: @color-search-font;
+ }
+}
+
+#pagination {
+ clear: both;
+
+ br {
+ clear: both;
+ }
+}
+
+#apis {
+ margin-top: 8px;
+ clear: both;
+}
+
+#backToTop {
+ border: 1px solid #ddd;
+ margin: 0 0 0 2em;
+ padding: 0;
+ font-size: 1em;
+ box-shadow: 0px 0px 5px #CCC;
+ background: white;
+ position: fixed;
+ bottom: 85px;
+ left: @results-width;
+ transition: opacity 0.5s;
+ opacity: 0;
+
+ a {
+ display: block;
+ margin: 0;
+ padding: 0.6em;
+ }
+}
+
+@media screen and (max-width: 75em) {
+
+ #main_preferences, #main_about, #main_stats {
+ margin: 0.5em;
+ width: auto;
+ }
+
+ #suggestions, #answers {
+ margin-top: 1em;
+ }
+
+ #infoboxes {
+ position: inherit;
+ max-width: inherit;
+
+ .infobox {
+ clear:both;
+
+ img {
+ float: left;
+ max-width: 10em;
+ margin: 0.5em 0.5em 0.5em 0;
+ }
+ }
+
+ }
+
+ #sidebar {
+ position: static;
+ max-width: @results-width;
+ margin: 0 0 2px 0;
+ padding: 0;
+ float: none;
+ border: none;
+ width: auto;
+
+ input {
+ border: 0;
+ }
+ }
+
+ #apis {
+ display: none;
+ }
+
+ #search_url {
+ display: none;
+ }
+
+ .result {
+ border-bottom: 1px solid @color-result-top-border;
+ margin: 0;
+ padding-top: 8px;
+ padding-bottom: 6px;
+
+ h3 {
+ margin: 0 0 1px 0;
+ }
+
+ .thumbnail {
+ max-width: 98%;
+ }
+
+ .url {
+
+ span.url {
+ display: block;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ width: 100%;
+ }
+
+ a {
+ float: right;
+ padding: 0 0.5em;
+ }
+
+ }
+
+ .engines {
+ float: right;
+ padding: 0 0 3px 0;
+ }
+ }
+
+ .result-images {
+ border-bottom: none !important;
+ }
+
+ .image_result {
+ max-width: 98%;
+ img {
+ max-width: 98%;
+ }
+ }
+}
+
+
+#main_results div#results.only_template_images {
+ flex-direction: column;
+ width: auto;
+ display: flex;
+
+ #sidebar {
+ position: relative;
+ top: auto;
+ order: 2;
+ }
+
+ #urls {
+ position: relative;
+ order: 1;
+ }
+
+ #backToTop {
+ right: 0.5em;
+ left: auto;
+ }
+
+ #pagination {
+ position: relative;
+ order: 3;
+ }
+}
+
+
+@media screen and (max-width: @results-width) {
+
+ article[data-vim-selected]::before {
+ display: none;
+ content: "";
+ }
+
+ #linkto_preferences {
+ display: none;
+ postion: fixed !important;
+ top: 100px;
+ right: 0px;
+ }
+
+ #sidebar {
+ margin: 0 5px 2px 5px;
+ }
+
+ #corrections {
+ margin: 1em 5px 1em 5px;
+ }
+
+ #results {
+ margin: 0;
+ padding: 0;
+ width: initial;
+ }
+
+ #backToTop {
+ left: 40em;
+ bottom: 35px;
+ }
+
+ .result {
+ padding: 8px 10px 6px 10px;
+ }
+
+ .result-images {
+ margin: 0;
+ padding: 0;
+ border: none;
+ }
+
+}
+
+@media screen and (max-width: 35em) {
+
+ .result-videos {
+
+ img.thumbnail {
+ float: none !important;
+ }
+ .content {
+ overflow: inherit;
+ }
+
+ }
+
+}
+
+pre code {
+ white-space: pre-wrap;
+}
diff --git a/searx/static/themes/simple/src/less/toolkit.less b/searx/static/themes/simple/src/less/toolkit.less
new file mode 100644
index 000000000..c381af802
--- /dev/null
+++ b/searx/static/themes/simple/src/less/toolkit.less
@@ -0,0 +1,553 @@
+// other solution : http://stackoverflow.com/questions/1577598/how-to-hide-parts-of-html-when-javascript-is-disabled/13857783#13857783
+html.no-js .hide_if_nojs {
+ display: none;
+}
+
+html.js .show_if_nojs {
+ display: none;
+}
+
+.center {
+ text-align: center;
+}
+
+.right {
+ float: right ;
+}
+
+.left {
+ float: left;
+}
+
+.invisible {
+ display: none !important;
+}
+
+.list-unstyled {
+ list-style-type: none;
+
+ li {
+ margin-top: 4px;
+ margin-bottom: 4px;
+ }
+}
+
+.danger {
+ background-color: @color-error-background;
+}
+
+.warning {
+ background: @color-warning-background;
+}
+
+.success {
+ background: @color-success-background;
+}
+
+.badge {
+ display: inline-block;
+ color: #fff;
+ background-color: #777;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ min-width: 10px;
+ padding: 1px 5px;
+ border-radius: 5px;
+}
+
+// kbd
+kbd {
+ padding: 2px 4px;
+ margin: 1px;
+ font-size: 90%;
+ color: white;
+ background: black;
+}
+
+// table
+table {
+
+ width: 100%;
+
+ &.striped {
+ tr {
+ border-bottom: 1px solid @color-settings-tr-hover;
+ }
+ }
+}
+
+th {
+ padding: 0.4em;
+}
+
+td {
+ padding: 0 4px;
+}
+
+tr {
+ &:hover {
+ background: @color-settings-tr-hover;
+ }
+}
+
+// pre
+.pre() {
+ display: block;
+ font-size: 0.8em;
+ word-break: break-all;
+ margin: 0.1em;
+ .select-all-on-focus();
+}
+
+div.selectable_url {
+ display: block;
+ border: 1px solid @color-result-search-url-border;
+ padding: 4px;
+ color: @color-result-search-url-font;
+ width: 100%;
+ display: block;
+ margin: 0.1em;
+ overflow: hidden;
+ height: 1.2em;
+ line-height: 1.2em;
+
+ pre {
+ .pre();
+ }
+}
+
+// dialog
+.dialog() {
+ position: relative;
+ width: 70%;
+ padding: 1em 1em 1em 2.7em;
+ margin: 0em 8% 1em 8%;
+ border: 1px solid black;
+ border-radius: 4px;
+ text-align: left;
+
+ &:before {
+ position: absolute;
+ top: 0.5em;
+ left: 0.5em;
+ font-family:"ion";
+ font-size: 1.5em;
+ }
+
+ .close {
+ float:right;
+ position: relative;
+ top: -3px;
+ color: inherit;
+ font-size: 1.5em;
+ }
+
+ ul, ol, p {
+ margin: 1px 0 0 0;
+ }
+
+ table {
+ width: auto;
+ }
+
+ tr {
+ vertical-align: text-top;
+
+ &:hover {
+ background: transparent;
+ }
+ }
+
+ td {
+ padding: 0 1em 0 0;
+ }
+
+
+ h4 {
+ margin-top: 0.3em;
+ margin-bottom: 0.3em;
+ }
+
+}
+
+.dialog-error {
+ .dialog();
+ color: @color-error;
+ background: @color-error-background;
+ border-color: @color-error;
+ .ion-error();
+}
+
+.dialog-warning {
+ .dialog();
+ color: @color-warning;
+ background: @color-warning-background;
+ border-color: @color-warning;
+ .ion-warning();
+}
+
+.dialog-modal {
+ .dialog();
+ background: white;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ /* bring your own prefixes */
+ transform: translate(-50%, -50%);
+ z-index: 100000;
+ margin: 0 50% 0 0;
+ box-shadow: 0 0 1em;
+}
+
+// btn-collapse
+.btn-collapse {
+ cursor: pointer;
+}
+
+//
+.scrollx {
+ overflow-x: auto;
+ overflow-y: hidden;
+ display: block;
+ padding: 0;
+ margin: 0;
+ border: none;
+}
+
+/* -- tabs --*/
+.tabs .tabs > label {
+ font-size: 90%;
+}
+
+.tabs {
+ .flexbox();
+ flex-wrap: wrap;
+ width: 100%;
+ min-width: 100%;
+
+ & > * {
+ order: 2;
+ }
+
+ & > input[type=radio] {
+ display: none;
+ }
+
+ & > label {
+ order: 1;
+ padding: 0.7em;
+ margin: 0 0.7em;
+ letter-spacing:0.5px;
+ text-transform: uppercase;
+
+ border: solid white;
+ border-width: 0px 0px 2px 0;
+
+ .disable-user-select();
+ cursor: pointer;
+ }
+
+ & > label:hover {
+ border-bottom: 2px solid @color-categories-item-border-selected;
+ }
+
+ & > section {
+ min-width: 100%;
+ padding: 0.7rem 0;
+ box-sizing: border-box;
+ border-top: 1px solid black;
+ display: none;
+ }
+
+ // default selection
+ & > label:last-of-type {
+ border-bottom: 2px solid @color-categories-item-border-selected;
+ background: @color-categories-item-selected;
+ color: @color-categories-item-selected-font;
+ font-weight: bold;
+ letter-spacing:-0.1px;
+ }
+
+ & > section:last-of-type {
+ display: block;
+ }
+
+}
+
+html body .tabs > input:checked {
+ ~ section {
+ display: none;
+ }
+ ~ label {
+ position: inherited;
+ background: inherit;
+ border-bottom: 2px solid transparent;
+ font-weight: normal;
+ color: inherit;
+
+ &:hover {
+ border-bottom: 2px solid @color-categories-item-border-selected;
+ }
+ }
+ + label {
+ border-bottom: 2px solid @color-categories-item-border-selected;
+ background: @color-categories-item-selected;
+ color: @color-categories-item-selected-font;
+ font-weight: bold;
+ letter-spacing:-0.1px;
+ }
+ + label + section {
+ display: block;
+ }
+}
+
+/* -- select -- */
+select {
+ height: 28px;
+ margin: 0 1em 0 0;
+ padding: 2px 8px 2px 0 !important;
+ color: @color-search-font;
+ font-size: 12px;
+ z-index: 2;
+
+ &:hover, &:focus {
+ cursor: pointer;
+ }
+}
+
+@supports ((background-position-x: 100%) and ((appearance: none) or (-webkit-appearance: none) or (-moz-appearance: none))) {
+
+ select {
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ border: none;
+ border-bottom: 1px solid #d7d7d7;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwb2x5Z29uIHBvaW50cz0iMTI4LDE5MiAyNTYsMzIwIDM4NCwxOTIiLz48L2c+PC9zdmc+Cg==) no-repeat;
+ background-position-x: 105%;
+ background-size: 2em;
+ background-origin: content-box;
+ outline: medium none;
+
+ &:hover, &:focus {
+ border-bottom: 1px solid @color-search-border;
+ }
+
+ }
+
+}
+
+/* -- checkbox-onoff -- */
+@supports (border-radius: 50px) {
+ .checkbox-onoff {
+ display: inline-block;
+ width: 40px;
+ height: 10px;
+ background: #dcdcdc;
+ margin: 8px auto;
+ position: relative;
+ border-radius: 50px;
+ label {
+ display: block;
+ width: 20px;
+ height: 20px;
+ position: absolute;
+ top: -5px;
+ cursor: pointer;
+ border-radius: 50px;
+ box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.3);
+ transition: all 0.4s ease;
+
+ left: 27px;
+ background-color: #3498DB;
+ }
+ input[type=checkbox] {
+ visibility: hidden;
+ &:checked + label {
+ left: -5px;
+ background: #dcdcdc;
+ }
+ }
+ }
+}
+
+/* -- checkbox --*/
+@supports (transform: rotate(-45deg)) {
+ .checkbox {
+ width: 20px;
+ position: relative;
+ margin: 20px auto;
+ label {
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: white;
+ border-radius: 4px;
+ box-shadow: inset 0px 1px 1px white, 0px 1px 4px rgba(0,0,0,0.5);
+ &:after {
+ content: '';
+ width: 9px;
+ height: 5px;
+ position: absolute;
+ top: 4px;
+ left: 4px;
+ border: 3px solid #333;
+ border-top: none;
+ border-right: none;
+ background: transparent;
+ opacity: 0;
+ transform: rotate(-45deg);
+ }
+ }
+
+ input[type=checkbox] {
+ visibility: hidden;
+ &:checked + label:after {
+ border-color: #3498DB;
+ opacity: 1;
+ }
+ }
+
+ // disabled : can''t be focused, show only the check mark
+ input[disabled] + label {
+ background-color: transparent !important;
+ box-shadow: none !important;
+ cursor: inherit;;
+ }
+
+ // if not checked and possible to checked then display a "light" check mark on hover
+ input:not(:checked):not([readonly]):not([disabled]) + label:hover::after {
+ opacity: 0.5;
+ }
+ }
+}
+
+@media screen and (max-width: 50em) {
+ .tabs > label {
+ width: 100%;
+ }
+}
+
+/* -- loader -- */
+.loader,
+.loader:after {
+ border-radius: 50%;
+ width: 2em;
+ height: 2em;
+}
+.loader {
+ margin: 1em auto;
+ font-size: 10px;
+ position: relative;
+ text-indent: -9999em;
+ border-top: 0.5em solid rgba(0, 0, 0, 0.2);
+ border-right: 0.5em solid rgba(0, 0, 0, 0.2);
+ border-bottom: 0.5em solid rgba(0, 0, 0, 0.2);
+ border-left: 0.5em solid rgba(255, 255, 255, 0);
+ -webkit-transform: translateZ(0);
+ -ms-transform: translateZ(0);
+ transform: translateZ(0);
+ -webkit-animation: load8 1.2s infinite linear;
+ animation: load8 1.2s infinite linear;
+}
+@-webkit-keyframes load8 {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+@keyframes load8 {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+/* -- engine-tooltip -- */
+.engine-tooltip {
+ display: none;
+ position: absolute;
+ padding: 0.5rem 1rem;
+ margin: 0rem 0 0 2rem;
+ border: 1px solid #ddd;
+ box-shadow: 2px 2px 2px 0px rgba(0,0,0,0.1);
+ background: white;
+ font-size: 14px;
+ font-weight: normal;
+ z-index: 1000000;
+ text-align: left;
+}
+
+th:hover .engine-tooltip, td:hover .engine-tooltip, .engine-tooltip:hover {
+ display: inline-block;
+}
+
+/* -- stacked bar chart -- */
+.stacked-bar-chart {
+ margin: 0;
+ padding: 0 0.125rem 0 4rem;
+ width: 100%;
+ width: -moz-available;
+ width: -webkit-fill-available;
+ width: fill;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+ display: inline-flex;
+}
+
+.stacked-bar-chart-value {
+ width: 3rem;
+ display: inline-block;
+ position: absolute;
+ padding: 0 0.5rem;
+ text-align: right;
+}
+
+.stacked-bar-chart-base {
+ display:flex;
+ flex-shrink: 0;
+ flex-grow: 0;
+ flex-basis: unset;
+}
+
+.stacked-bar-chart-median {
+ .stacked-bar-chart-base();
+ background: @stacked-bar-chart;
+ border: 1px solid fade(@stacked-bar-chart, 90%);
+ padding: 0.3rem 0;
+}
+
+.stacked-bar-chart-rate80 {
+ .stacked-bar-chart-base();
+ background: transparent;
+ border: 1px solid fade(@stacked-bar-chart, 30%);
+ padding: 0.3rem 0;
+}
+
+.stacked-bar-chart-rate95 {
+ .stacked-bar-chart-base();
+ background: transparent;
+ border-bottom: 1px dotted fade(@stacked-bar-chart, 50%);
+ padding: 0;
+}
+
+.stacked-bar-chart-rate100 {
+ .stacked-bar-chart-base();
+ background: transparent;
+ border-left: 1px solid fade(@stacked-bar-chart, 90%);
+ padding: 0.4rem 0;
+ width: 1px;
+}
diff --git a/searx/static/themes/simple/src/less/toolkit_loader.less b/searx/static/themes/simple/src/less/toolkit_loader.less
new file mode 100644
index 000000000..7ef19c19b
--- /dev/null
+++ b/searx/static/themes/simple/src/less/toolkit_loader.less
@@ -0,0 +1,41 @@
+.loader,
+.loader:after {
+ border-radius: 50%;
+ width: 10em;
+ height: 10em;
+}
+.loader {
+ margin: 60px auto;
+ font-size: 10px;
+ position: relative;
+ text-indent: -9999em;
+ border-top: 1.1em solid rgba(255, 255, 255, 0.2);
+ border-right: 1.1em solid rgba(255, 255, 255, 0.2);
+ border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);
+ border-left: 1.1em solid #ffffff;
+ -webkit-transform: translateZ(0);
+ -ms-transform: translateZ(0);
+ transform: translateZ(0);
+ -webkit-animation: load8 1.1s infinite linear;
+ animation: load8 1.1s infinite linear;
+}
+@-webkit-keyframes load8 {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+@keyframes load8 {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+} \ No newline at end of file