window . searxng = function ( t , i ) { "use strict" ; if ( t . Element ) { ( function ( e ) { e . matches = e . matches || e . matchesSelector || e . webkitMatchesSelector || e . msMatchesSelector || function ( e ) { var t = this , n = ( t . parentNode || t . document ) . querySelectorAll ( e ) , r = - 1 ; while ( n [ ++ r ] && n [ r ] != t ) ; return ! ! n [ r ] } } ) ( Element . prototype ) } function s ( e , t , n ) { try { e . call ( t , n ) } catch ( e ) { console . log ( e ) } } var a = window . searxng || { } ; a . on = function ( r , e , o , t ) { t = t || false ; if ( typeof r !== "string" ) { r . addEventListener ( e , o , t ) } else { i . addEventListener ( e , function ( e ) { var t = e . target || e . srcElement , n = false ; while ( t && t . matches && t !== i && ! ( n = t . matches ( r ) ) ) t = t . parentElement ; if ( n ) s ( o , t , e ) } , t ) } } ; a . ready = function ( e ) { if ( document . readyState != "loading" ) { e . call ( t ) } else { t . addEventListener ( "DOMContentLoaded" , e . bind ( t ) ) } } ; a . http = function ( r , o , i = null ) { return new Promise ( function ( e , t ) { try { var n = new XMLHttpRequest ; n . open ( r , o , true ) ; n . timeout = 2e4 ; n . onload = function ( ) { if ( n . status == 200 ) { e ( n . response , n . responseType ) } else { t ( Error ( n . statusText ) ) } } ; n . onerror = function ( ) { t ( Error ( "Network Error" ) ) } ; n . onabort = function ( ) { t ( Error ( "Transaction is aborted" ) ) } ; n . ontimeout = function ( ) { t ( Error ( "Timeout" ) ) } ; if ( i ) { n . send ( i ) } else { n . send ( ) } } catch ( e ) { t ( e ) } } ) } ; a . loadStyle = function ( e ) { var t = a . settings . theme _static _path + "/" + e , n = "style_" + e . replace ( "." , "_" ) , r = i . getElementById ( n ) ; if ( r === null ) { r = i . createElement ( "link" ) ; r . setAttribute ( "id" , n ) ; r . setAttribute ( "rel" , "stylesheet" ) ; r . setAttribute ( "type" , "text/css" ) ; r . setAttribute ( "href" , t ) ; i . body . appendChild ( r ) } } ; a . loadScript = function ( e , t ) { var n = a . settings . theme _static _path + "/" + e , r = "script_" + e . replace ( "." , "_" ) , o = i . getElementById ( r ) ; if ( o === null ) { o = i . createElement ( "script" ) ; o . setAttribute ( "id" , r ) ; o . setAttribute ( "src" , n ) ; o . onload = t ; o . onerror = function ( ) { o . setAttribute ( "error" , "1" ) } ; i . body . appendChild ( o ) } else if ( ! o . hasAttribute ( "error" ) ) { try { t . apply ( o , [ ] ) } catch ( e ) { console . log ( e ) } } else { console . log ( "callback not executed : script '" + n + "' not loaded." ) } } ; a . insertBefore = function ( e , t ) { t . parentNode . insertBefore ( e , t ) } ; a . insertAfter = function ( e , t ) { t . parentNode . insertAfter ( e , t . nextSibling ) } ; a . on ( ".close" , "click" , function ( ) { this . parentNode . classList . add ( "invisible" ) } ) ; function e ( ) { for ( var e of i . getElementsByTagName ( "body" ) [ 0 ] . classList . values ( ) ) { if ( e . endsWith ( "_endpoint" ) ) { return e . split ( "_" ) [ 0 ] } } return "" } a . endpoint = e ( ) ; return a } ( window , document ) ; searxng . ready ( function ( ) { "use strict" ; searxng . infinite _scroll _supported = "IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window . IntersectionObserverEntry . prototype ; if ( searxng . endpoint !== "results" ) { return } if ( ! searxng . infinite _scroll _supported ) { console . log ( "IntersectionObserver not supported" ) ; return } let i = document ; var s = i . getElementById ( "results" ) . classList . contains ( "only_template_images" ) ; function n ( ) { var e = i . createElement ( "div" ) ; e . classList . add ( "loader" ) ; return e } function r ( t , e ) { t . textContent = "" ; e . forEach ( e => t . appendChild ( e ) ) } function o ( o ) { var e = i . querySelector ( "#pagination form.next_page" ) ; if ( ! e ) { return } r ( i . querySelector ( "#pagination" ) , [ n ( ) ] ) ; var t = new FormData ( e ) ; searxng . http ( "POST" , i . querySelector ( "#search" ) . getAttribute ( "action" ) , t ) . then ( function ( e ) { var t = ( new DOMParser ) . parseFromString ( e , "text/html" ) ; var n = t . querySelectorAll ( "#urls article" ) ; var r = t . querySelector ( "#pagination" ) ; i . querySelector ( "#pagination" ) . remove ( ) ; if ( n . length > 0 && ! s ) { i . querySelector ( "#urls" ) . appendChild ( i . createElement ( "hr" ) ) } n . forEach ( e => { i . querySelector ( "#urls" ) . appendChild ( e ) } ) ; if ( r ) { i . querySelector ( "#results" ) . appendChild ( r ) ; o ( ) } } ) . catch ( function ( e ) { console . log ( e ) ; var t = i . createElement ( "div" ) ; t . textContent = searxng . settings . translations . error _loading _next _page ; t . classList . add ( "dialog-error" ) ; t . setAttribute ( "role" , "alert" ) ; r ( i . querySelector ( "#pagination" ) , [ t ] ) } ) } if ( searxng . settings . infinite _scroll && searxng . infinite _scroll _supported ) { const a = { rootMargin : "20rem" } ; const l = "article.result:last-child" ; const u = new IntersectionObserver ( e => { const t = e [ 0 ] ; if ( t . isIntersecting ) { u . unobserve ( t . target ) ; o ( ( ) => u . observe ( i . querySelector ( l ) , a ) ) } } ) ; u . observe ( i . querySelector ( l ) , a ) } } ) ; searxng . ready ( function ( ) { function e ( e ) { while ( e !== undefined ) { if ( e . classList . contains ( "detail" ) ) { return true } if ( e . classList . contains ( "result" ) ) { return false } e = e . parentNode } return false } function n ( e ) { while ( e !== undefined ) { if ( e . classList . contains ( "result" ) ) { return e } e = e . parentNode } return undefined } function r ( e ) { return e && e . classList . contains ( "result-images" ) } searxng . on ( ".result" , "click" , function ( t ) { if ( ! e ( t . target ) ) { i ( this ) ( true , true ) ; let e = n ( t . target ) ; if ( r ( e ) ) { t . preventDefault ( ) ; searxng . selectImage ( e ) } } } ) ; searxng . on ( ".result a" , "focus" , function ( t ) { if ( ! e ( t . target ) ) { let e = n ( t . target ) ; if ( e && e . getAttribute ( "data-vim-selected" ) === null ) { i ( e ) ( true ) } if ( r ( e ) ) { searxng . selectImage ( e ) } } } , true ) ; var t = { Escape : { key : "ESC" , fun : a , des : "remove focus from the focused input" , cat : "Control" } , c : { key : "c" , fun : b , des : "copy url of the selected result to the clipboard" , cat : "Results" } , h : { key : "h" , fun : y , des : "toggle help window" , cat : "Other" } , i : { key : "i" , fun : m , des : "focus on the search input" , cat : "Control" } , n : { key : "n" , fun : u ( ) , des : "go to next page" , cat : "Results" } , o : { key : "o" , fun : g ( false ) , des : "open search result" , cat : "Results" } , p : { key : "p" , fun : c ( ) , des : "go to previous page" , cat : "Results" } , r : { key : "r" , fun : s , des : "reload page from the server" , cat : "Control" } , t : { key : "t" , fun : g ( true ) , des : "open the result in a new tab" , cat : "Results" } } ; var o = { default : Object . assign ( { ArrowLeft : { key : "←" , fun : i ( "up" ) , des : "select previous search result" , cat : "Results" } , ArrowRight : { key : "→" , fun : i ( "down" ) , des : "select next search result" , cat : "Results" } } , t ) , vim : Object . assign ( { b : { key : "b" , fun : f ( - window . innerHeight ) , des : "scroll one page up" , cat : "Navigation" } , f : { key : "f" , fun : f ( window . innerHeight ) , des : "scroll one page down" , cat : "Navigation" } , u : { key : "u" , fun : f ( - window . innerHeight / 2 ) , des : "scroll half a page up" , cat : "Navigation" } , d : { key : "d" , fun : f ( window . innerHeight / 2 ) , des : "scroll half a page down" , cat : "Navigation" } , g : { key : "g" , fun : h ( - document . body . scrollHeight , "top" ) , des : "scroll to the top of the page" , cat : "Navigation" } , v : { key : "v" , fun : h ( document . body . scrollHeight , "bottom" ) , des : "scroll to the bottom of the page" , cat : "Navigation" } , k : { key : "k" , fun : i ( "up" ) , des : "select previous search result" , cat : "Results" } , j : { key : "j" , fun : i ( "down" ) , des : "select next search result" , cat : "Results" } , y : { key : "y" , fun : b , des : "copy url of the selected result to the clipboard" , cat : "Results" } } , t ) } ; var d = o [ searxng . settings . hotkeys ] || o . default ; searxng . on ( document , "keydown" , function ( e ) { if ( Object . prototype . hasOwnProperty . call ( d , e . key ) && ! e . ctrlKey && ! e . altKey && ! e . shiftKey && ! e . metaKey ) { var t = e . target . tagName . toLowerCase ( ) ; if ( e . key === "Escape" ) { d [ e . key ] . fun ( e ) } else { if ( e . target === document . body || t === "a" || t === "button" ) { e . preventDefault ( ) ; d [ e . key ] . fun ( ) } } } } ) ; function i ( f ) { return function ( e , t ) { var n = document . querySelector ( ".result[data-vim-selected]" ) , r = f ; if ( n === null ) { n = document . querySelector ( ".result" ) ; if ( n === null ) { return } if ( f === "down" || f === "up" ) { r = n } } var o , i = document . querySelectorAll ( ".result" ) ; i = Array . from ( i ) ; if ( typeof r !== "string" ) { o = r } else { switch ( r ) { case "visible" : var s = document . documentElement . scrollTop || document . body . scrollTop ; var a = s + document . documentElement . clientHeight ; for ( var l = 0 ; l < i . length ; l ++ ) { o = i [ l ] ; var u = o . offsetTop ; var c = u + o . clientHeight ; if ( c <= a && u > s ) { break } } break ; case "down" : o = i [ i . indexOf ( n ) + 1 ] || n ; break ; case "up" : o = i [ i . indexOf ( n ) - 1 ] || n ; break ; case "bottom" : o = i [ i . length - 1 ] ; break ; case "top" : default : o = i [ 0 ] } } if ( o ) { n . removeAttribute ( "data-vim-selected" ) ; o . setAttribute ( "data-vim-selected" , "true" ) ; if ( ! t ) { var d = o . querySelector ( "h3 a" ) || o . querySelector ( "a" ) ; if ( d !== null ) { d . focus ( ) } } if ( ! e ) { p ( ) } } } } function s ( ) { document . location . reload ( true ) } function a ( e ) { const t = e . target . tagName . toLowerCase ( ) ; if ( document . activeElement && ( t === "input" || t === "select" || t === "textarea" ) ) { document . activeElement . blur ( ) } else { searxng . closeDetail ( ) } } function l ( t ) { return function ( ) { var e = document . querySelector ( t ) ; if ( e ) { e . click ( ) } } } function u ( ) { return l ( 'nav#pagination .next_page button[type="submit"]' ) } function c ( ) { return l ( 'nav#pagination .previous_page button[type="submit"]' ) } function p ( ) { var e = document . querySelector ( ".result[data-vim-selected]" ) ; if ( e === null ) { return } var t = document . documentElement . scrollTop || document . body . scrollTop , n = document . documentElement . clientHeight , r = e . offsetTop , o = r + e . clientHeight , i = 120 ; if ( e . previousElementSibling === null && o < n ) { window . scroll ( window . scrollX , 0 ) ; return } if ( t > r - i ) { window . scroll ( window . scrollX , r - i ) } else { var s = t + n ; if ( s < o + i ) { window . scroll ( window . scrollX , o - n + i ) } } } function f ( e ) { return function ( ) { window . scrollBy ( 0 , e ) ; i ( "visible" ) ( ) } } function h ( e , t ) { return function ( ) { window . scrollTo ( 0 , e ) ; i ( t ) ( ) } } function m ( ) { window . scrollTo ( 0 , 0 ) ; var e = document . querySelector ( "#q" ) ; e . focus ( ) ; if ( e . setSelectionRange ) { var t = e . value . length ; e . setSelectionRange ( t , t ) } } function g ( n ) { return function ( ) { var e = document . querySelector ( ".result[data-vim-selected] h3 a" ) ; if ( e === null ) { e = document . querySelector ( ".result[data-vim-selected] > a" ) } if ( e !== null ) { var t = e . getAttribute ( "href" ) ; if ( n ) { window . open ( t ) } else { window . location . href = t } } } } function v ( e ) { var n = { } ; for ( var t in d ) { var r = d [ t ] ; n [ r . cat ] = n [ r . cat ] || [ ] ; n [ r . cat ] . push ( r ) } var o = Object . keys ( n ) . sort ( function ( e , t ) { return n [ t ] . length - n [ e ] . length } ) ; if ( o . length === 0 ) { return } var i = '<a href="#" class="close" aria-label="close" title="close">× </a>' ; i += "<h3>How to navigate SearXNG with hotkeys</h3>" ; i += "<table>" ; for ( var s = 0 ; s < o . length ; s ++ ) { var a = n [ o [ s ] ] ; var l = s === o . length - 1 ; var u = s % 2 === 0 ; if ( u ) { i += "<tr>" } i += "<td>" ; i += "<h4>" + a [ 0 ] . cat + "</h4>" ; i += '<ul class="list-unstyled">' ; for ( var c in a ) { i += "<li><kbd>" + a [ c ] . key + "</kbd> " + a [ c ] . des + "</li>" } i += "</ul>" ; i += "</td>" ; if ( ! u || l ) { i += "</tr>" } } i += "</table>" ; e . innerHTML = i } function y ( ) { var e = document . querySelector ( "#vim-hotkeys-help" ) ; if ( e === undefined || e === null ) { e = document . createElement ( "div" ) ; e . id = "vim-hotkeys-help" ; e . className = "dialog-modal" ; v ( e ) ; var t = document . getElementsByTagName ( "body" ) [ 0 ] ; t . appendChild ( e ) } else { e . classList . toggle ( "invisible" ) ; return } } function b ( ) { var e = document . querySelector ( ".result[data-vim-selected] h3 a" ) ; if ( e === null ) return ; const t = e . getAttribute ( "href" ) ; navigator . clipboard . writeText ( t ) } searxng . scrollPageToSelected = p ; searxng . selectNext = i ( "down" ) ; searxng . selectPrevious = i ( "up" ) } ) ; ( function ( e , t , n ) { "use strict" ; n . ready ( function ( ) { n . on ( ".searxng_init_map" , "click" , function ( e ) { this . classList . remove ( "searxng_init_map" ) ; var d = this . dataset . leafletTarget ; var f = parseFloat ( this . dataset . mapLon ) ; var p = parseFloat ( this . dataset . mapLat ) ; var h = parseFloat ( this . dataset . mapZoom ) ; var m = JSON . parse ( this . dataset . mapBoundingbox ) ; var g = JSON . parse ( this . dataset . mapGeojson ) ; n . loadStyle ( "css/leaflet.css" ) ; n . loadScript ( "js/leaflet.js" , function ( ) { var e = null ; if ( m ) { var t = L . latLng ( m [ 0 ] , m [ 2 ] ) ; var n = L . latLng ( m [ 1 ] , m [ 3 ] ) ; e = L . latLngBounds ( t , n ) } var r = L . map ( d ) ; var o = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" ; var i = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors' ; var s = new L . TileLayer ( o , { minZoom : 1 , maxZoom : 19 , attribution : i } ) ; var a = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png" ; var l = 'Wikimedia maps | Maps data © <a href="https://openstreetmap.org">OpenStreetMap contributors</a>' ; var u = new L . TileLayer ( a , { minZoom : 1 , maxZoom : 19 , attribution : l } ) ; if ( e ) { setTimeout ( function ( ) { r . fitBounds ( e , { maxZoom : 17 } ) } , 0 ) } else if ( f && p ) { if ( h ) { r . setView ( new L . latLng ( p , f ) , h ) } else { r . setView ( new L . latLng ( p , f ) , 8 ) } } r . addLayer ( s ) ; var c = { "OSM Mapnik" : s , "OSM Wikimedia" : u } ; L . control . layers ( c ) . addTo ( r ) ; if ( g ) { L . geoJson ( g ) . addTo ( r ) } } ) ; e . preventDefault ( ) } ) } ) } ) ( window , document , window . searxng ) ; ( function ( e , l , u ) { "use strict" ; if ( u . endpoint !== "preferences" ) { return } u . ready ( function ( ) { let o = null ; function e ( ) { if ( o == null ) { u . http ( "GET" , "engine_descriptions.json" ) . then ( function ( e ) { o = JSON . parse ( e ) ; for ( const [ t , n ] of Object . entries ( o ) ) { let e = l . querySelectorAll ( '[data-engine-name="' + t + '"] .engine-description' ) ; for ( const r of e ) { let e = " (<i>" + u . settings . translations . Source + ": " + n [ 1 ] + "</i>)" ; r . innerHTML = n [ 0 ] + e } } } ) } } for ( const a of l . querySelectorAll ( "[data-engine-name]" ) ) { u . on ( a , "mouseenter" , e ) } const t = l . querySelectorAll ( ".enable-all-engines" ) ; const n = l . querySelectorAll ( ".disable-all-engines" ) ; const r = l . querySelectorAll ( "tbody input[type=checkbox][class~=checkbox-onoff]" ) ; const i = t => { for ( const e of r ) { if ( e . offsetParent !== null ) e . checked = ! t } } ; for ( const a of t ) { u . on ( a , "click" , ( ) => i ( true ) ) } for ( const a of n ) { u . on ( a , "click" , ( ) => i ( false ) ) } const s = l . querySelector ( "#copy-hash" ) ; u . on ( s , "click" , e => { e . preventDefault ( ) ; navigator . clipboard . writeText ( s . dataset . hash ) ; s . innerText = s . dataset . copiedText } ) } ) } ) ( window , document , window . searxng ) ; ( function ( e , a , l ) { "use strict" ; if ( l . endpoint !== "results" ) { return } l . ready ( function ( ) { a . querySelectorAll ( "#urls img" ) . forEach ( e => e . addEventListener ( "error" , ( ) => { e . src = window . searxng . settings . theme _static _path + "/img/img_load_error.svg" } , { once : true } ) ) ; if ( a . querySelector ( "#search_url button#copy_url" ) ) { a . querySelector ( "#search_url button#copy_url" ) . style . display = "block" } l . on ( ".btn-collapse" , "click" , function ( ) { var e = this . getAttribute ( "data-btn-text-collapsed" ) ; var t = this . getAttribute ( "data-btn-text-not-collapsed" ) ; var n = this . getAttribute ( "data-target" ) ; var r = a . querySelector ( n ) ; var o = this . innerHTML ; if ( this . classList . contains ( "collapsed" ) ) { o = o . replace ( e , t ) } else { o = o . replace ( t , e ) } this . innerHTML = o ; this . classList . toggle ( "collapsed" ) ; r . classList . toggle ( "invisible" ) } ) ; l . on ( ".media-loader" , "click" , function ( ) { var e = this . getAttribute ( "data-target" ) ; var t = a . querySelector ( e + " > iframe" ) ; var n = t . getAttribute ( "src" ) ; if ( n === null || n === undefined || n === false ) { t . setAttribute ( "src" , t . getAttribute ( "data-src" ) ) } } ) ; l . on ( "#copy_url" , "click" , function ( ) { var e = this . parentElement . querySelector ( "pre" ) ; navigator . clipboard . writeText ( e . innerText ) ; this . innerText = this . dataset . copiedText } ) ; let n ; const i = a . createElement ( "div" ) ; i . classList . add ( "loader" ) ; const r = new Image ; const s = ( e , t ) => { if ( n ) clearTimeout ( n ) ; n = setTimeout ( ( ) => { r . src = e } , 1e3 ) ; r . onload = ( ) => { t ( ) ; i . remove ( ) } ; r . onerror = ( ) => { i . remove ( ) } } ; l . selectImage = e => { a . getElementById ( "results" ) . classList . add ( "image-detail-open" ) ; window . location . hash = "#image-viewer" ; l . scrollPageToSelected ( ) ; if ( ! e ) return ; const t = e . querySelector ( ".result-images-source img" ) ; if ( ! t ) return ; const n = t . getAttribute ( "data-src" ) ; if ( ! n ) return ; const r = e . querySelector ( ".image_thumbnail" ) ; t . src = r . src ; const o = e . querySelector ( ".detail" ) ; o . appendChild ( i ) ; s ( n , ( ) => { t . src = n ; t . removeAttribute ( "data-src" ) } ) } ; l . closeDetail = function ( ) { a . getElementById ( "results" ) . classList . remove ( "image-detail-open" ) ; if ( window . location . hash == "#image-viewer" ) window . history . back ( ) ; l . scrollPageToSelected ( ) } ; l . on ( ".result-detail-close" , "click" , e => { e . preventDefault ( ) ; l . closeDetail ( ) } ) ; l . on ( ".result-detail-previous" , "click" , e => { e . preventDefault ( ) ; l . selectPrevious ( false ) } ) ; l . on ( ".result-detail-next" , "click" , e => { e . preventDefault ( ) ; l . selectNext ( false ) } ) ; window . addEventListener ( "hashchange" , ( ) => { if ( window . location . hash != "#image-viewer" ) l . closeDetail ( ) } ) ; a . querySelectorAll ( ".swipe-horizontal" ) . forEach ( e => { e . addEventListener ( "swiped-left" , function ( ) { l . selectNext ( false ) } ) ; e . addEventListener ( "swiped-right" , function ( ) { l . selectPrevious ( false ) } ) } ) ; e . addEventListener ( "scroll" , function ( ) { var e = a . getElementById ( "backToTop" ) , t = document . documentElement . scrollTop || document . body . scrollTop , n = a . getElementById ( "results" ) ; if ( e !== null ) { if ( t >= 100 ) { n . classList . add ( "scrolling" ) } else { n . classList . remove ( "scrolling" ) } } } , true ) } ) } ) ( window , document , window . searxng ) ; ( function ( e , o , i ) { "use strict" ; var n = "q" , s ; const a = window . matchMedia ( "only screen and (max-width: 50em)" ) . matches ; function l ( ) { if ( s . value . length > 0 ) { var e = document . getElementById ( "search" ) ; setTimeout ( e . submit . bind ( e ) , 0 ) } } function u ( t ) { var e = document . getElementById ( "clear_search" ) ; var n = function ( ) { if ( t . value . length === 0 ) { e . classList . add ( "empty" ) } else { e . classList . remove ( "empty" ) } } ; n ( ) ; e . addEventListener ( "click" , function ( e ) { t . value = "" ; t . focus ( ) ; n ( ) ; e . preventDefault ( ) } ) ; t . addEventListener ( "input" , n , false ) } i . ready ( function ( ) { s = o . getElementById ( n ) ; if ( s !== null ) { u ( s ) ; if ( i . settings . autocomplete ) { i . autocomplete = AutoComplete . call ( e , { Url : "./autocompleter" , EmptyMessage : i . settings . translations . no _item _found , HttpMethod : i . settings . method , HttpHeaders : { "Content-type" : "application/x-www-form-urlencoded" , "X-Requested-With" : "XMLHttpRequest" } , MinChars : i . settings . autocomplete _min , Delay : 300 , _Position : function ( ) { } , _Open : function ( ) { var t = this ; Array . prototype . forEach . call ( this . DOMResults . getElementsByTagName ( "li" ) , function ( e ) { if ( e . getAttribute ( "class" ) != "locked" ) { e . onmousedown = function ( ) { t . _Select ( e ) } } } ) } , _Select : function ( e ) { AutoComplete . defaults . _Select . call ( this , e ) ; var t = e . closest ( "form" ) ; if ( t ) { t . submit ( ) } } , _MinChars : function ( ) { if ( this . Input . value . indexOf ( "!" ) > - 1 ) { return 0 } else { return AutoComplete . defaults . _MinChars . call ( this ) } } , KeyboardMappings : Object . assign ( { } , AutoComplete . defaults . KeyboardMappings , { KeyUpAndDown _up : Object . assign ( { } , AutoComplete . defaults . KeyboardMappings . KeyUpAndDown _up , { Callback : function ( e ) { AutoComplete . defaults . KeyboardMappings . KeyUpAndDown _up . Callback . call ( this , e ) ; var t = this . DOMResults . querySelector ( "li.active" ) ; if ( t ) { AutoComplete . defaults . _Select . call ( this , t ) } } } ) , Tab : Object . assign ( { } , AutoComplete . defaults . KeyboardMappings . Enter , { Conditions : [ { Is : 9 , Not : false } ] , Callback : function ( e ) { if ( this . DOMResults . getAttribute ( "class" ) . indexOf ( "open" ) != - 1 ) { var t = this . DOMResults . querySelector ( "li.active" ) ; if ( t !== null ) { AutoComplete . defaults . _Select . call ( this , t ) ; e . preventDefault ( ) } } } } ) } ) } , "#" + n ) } AutoComplete . prototype . ajax = function ( e , t , n ) { if ( n === void 0 ) { n = true } if ( e . $AjaxTimer ) { window . clearTimeout ( e . $AjaxTimer ) } if ( n === true ) { e . $AjaxTimer = window . setTimeout ( AutoComplete . prototype . ajax . bind ( null , e , t , false ) , e . Delay ) } else { if ( e . Request ) { e . Request . abort ( ) } e . Request = t ; e . Request . send ( encodeURIComponent ( e . _QueryArg ( ) ) + "=" + encodeURIComponent ( e . _Pre ( ) ) ) } } ; if ( ! a && document . querySelector ( ".index_endpoint" ) ) { s . focus ( ) } } if ( s !== null && i . settings . search _on _category _select && o . querySelector ( ".search_filters" ) != null ) { i . on ( o . getElementById ( "safesearch" ) , "change" , l ) ; i . on ( o . getElementById ( "time_range" ) , "change" , l ) ; i . on ( o . getElementById ( "language" ) , "change" , l ) } const r = o . querySelectorAll ( "button.category_button" ) ; for ( let n of r ) { i . on ( n , "click" , e => { if ( e . shiftKey ) { e . preventDefault ( ) ; n . classList . toggle ( "selected" ) ; return } const t = o . querySelectorAll ( "button.category_button.selected" ) ; for ( let e of t ) { e . classList . remove ( "selected" ) } n . classList . add ( "selected" ) } ) } const t = o . querySelector ( "#search" ) ; if ( t != null ) { i . on ( t , "submit" , e => { e . preventDefault ( ) ; const n = o . querySelector ( "#selected-categories" ) ; if ( n ) { let t = [ ] ; for ( let e of r ) { if ( e . classList . contains ( "selected" ) ) { t . push ( e . name . replace ( "category_" , "" ) ) } } n . value = t . join ( "," ) } t . submit ( ) } ) } } ) } ) ( window , document , window . searxng ) ; ( function ( e ) { if ( typeof exports === "object" && typeof module !== "undefined" ) { module . exports = e ( ) } else if ( typeof define === "function" && define . amd ) { define ( [ ] , e ) } else { var t ; if ( typeof window !== "undefined" ) { t = window } else if ( typeof global !== "undefined" ) { t = global } else if ( typeof self !== "undefined" ) { t = self } else { t = this } t . AutoComplete = e ( ) } } ) ( function ( ) { var e , t , n ; return function ( ) { function c ( i , s , a ) { function l ( n , e ) { if ( ! s [ n ] ) { if ( ! i [ n ] ) { var t = "function" == typeof require && require ; if ( ! e && t ) return t ( n , ! 0 ) ; if ( u ) return u ( n , ! 0 ) ; var r = new Error ( "Cannot find module '" + n + "'" ) ; throw r . code = "MODULE_NOT_FOUND" , r } var o = s [ n ] = { exports : { } } ; i [ n ] [ 0 ] . call ( o . exports , function ( e ) { var t = i [ n ] [ 1 ] [ e ] ; return l ( t || e ) } , o , o . exports , c , i , s , a ) } return s [ n ] . exports } for ( var u = "function" == typeof require && require , e = 0 ; e < a . length ; e ++ ) l ( a [ e ] ) ; return l } return c } ( ) ( { 1 : [ function ( e , t , n ) {
"use strict" ; var l ; ( function ( e ) { e [ e [ "AND" ] = 0 ] = "AND" ; e [ e [ "OR" ] = 1 ] = "OR" } ) ( l || ( l = { } ) ) ; var i ; ( function ( e ) { e [ e [ "KEYDOWN" ] = 0 ] = "KEYDOWN" ; e [ e [ "KEYUP" ] = 1 ] = "KEYUP" } ) ( i || ( i = { } ) ) ; var r = function ( ) { function a ( t , e ) { if ( t === void 0 ) { t = { } } if ( e === void 0 ) { e = "[data-autocomplete]" } if ( Array . isArray ( e ) ) { e . forEach ( function ( e ) { new a ( t , e ) } ) } else if ( typeof e == "string" ) { var n = document . querySelectorAll ( e ) ; Array . prototype . forEach . call ( n , function ( e ) { new a ( t , e ) } ) } else { var r = a . merge ( a . defaults , t , { DOMResults : document . createElement ( "div" ) } ) ; a . prototype . create ( r , e ) ; return r } } a . prototype . create = function ( e , t ) { e . Input = t ; if ( e . Input . nodeName . match ( /^INPUT$/i ) && ( e . Input . hasAttribute ( "type" ) === false || e . Input . getAttribute ( "type" ) . match ( /^TEXT|SEARCH$/i ) ) ) { e . Input . setAttribute ( "autocomplete" , "off" ) ; e . _Position ( e ) ; e . Input . parentNode . appendChild ( e . DOMResults ) ; e . $Listeners = { blur : e . _Blur . bind ( e ) , destroy : a . prototype . destroy . bind ( null , e ) , focus : e . _Focus . bind ( e ) , keyup : a . prototype . event . bind ( null , e , i . KEYUP ) , keydown : a . prototype . event . bind ( null , e , i . KEYDOWN ) , position : e . _Position . bind ( e ) } ; for ( var n in e . $Listeners ) { e . Input . addEventListener ( n , e . $Listeners [ n ] ) } } } ; a . prototype . getEventsByType = function ( e , t ) { var n = { } ; for ( var r in e . KeyboardMappings ) { var o = i . KEYUP ; if ( e . KeyboardMappings [ r ] . Event !== undefined ) { o = e . KeyboardMappings [ r ] . Event } if ( o == t ) { n [ r ] = e . KeyboardMappings [ r ] } } return n } ; a . prototype . event = function ( e , t , n ) { var r = function ( e ) { if ( s === true && i . Operator == l . AND || s === false && i . Operator == l . OR ) { e = a . merge ( { Not : false } , e ) ; if ( e . hasOwnProperty ( "Is" ) ) { if ( e . Is == n . keyCode ) { s = ! e . Not } else { s = e . Not } } else if ( e . hasOwnProperty ( "From" ) && e . hasOwnProperty ( "To" ) ) { if ( n . keyCode >= e . From && n . keyCode <= e . To ) { s = ! e . Not } else { s = e . Not } } } } ; for ( var o in a . prototype . getEventsByType ( e , t ) ) { var i = a . merge ( { Operator : l . AND } , e . KeyboardMappings [ o ] ) , s = l . AND == i . Operator ; i . Conditions . forEach ( r ) ; if ( s === true ) { i . Callback . call ( e , n ) } } } ; a . prototype . makeRequest = function ( e , t , n ) { var r = Object . getOwnPropertyNames ( e . HttpHeaders ) , o = new XMLHttpRequest , i = e . _HttpMethod ( ) , s = e . _Url ( ) , a = e . _Pre ( ) , l = encodeURIComponent ( e . _QueryArg ( ) ) + "=" + encodeURIComponent ( a ) ; if ( i . match ( /^GET$/i ) ) { if ( s . indexOf ( "?" ) !== - 1 ) { s += "&" + l } else { s += "?" + l } } o . open ( i , s , true ) ; for ( var u = r . length - 1 ; u >= 0 ; u -- ) { o . setRequestHeader ( r [ u ] , e . HttpHeaders [ r [ u ] ] ) } o . onreadystatechange = function ( ) { if ( o . readyState == 4 && o . status == 200 ) { e . $Cache [ a ] = o . response ; t ( o . response ) } else if ( o . status >= 400 ) { n ( ) } } ; return o } ; a . prototype . ajax = function ( e , t , n ) { if ( n === void 0 ) { n = true } if ( e . $AjaxTimer ) { window . clearTimeout ( e . $AjaxTimer ) } if ( n === true ) { e . $AjaxTimer = window . setTimeout ( a . prototype . ajax . bind ( null , e , t , false ) , e . Delay ) } else { if ( e . Request ) { e . Request . abort ( ) } e . Request = t ; e . Request . send ( e . _QueryArg ( ) + "=" + e . _Pre ( ) ) } } ; a . prototype . cache = function ( e , t , n ) { var r = e . _Cache ( e . _Pre ( ) ) ; if ( r === undefined ) { var o = a . prototype . makeRequest ( e , t , n ) ; a . prototype . ajax ( e , o ) } else { t ( r ) } } ; a . prototype . destroy = function ( e ) { for ( var t in e . $Listeners ) { e . Input . removeEventListener ( t , e . $Listeners [ t ] ) } e . DOMResults . parentNode . removeChild ( e . DOMResults ) } ; a . merge = function ( ) { var e = { } , t ; for ( var n = 0 ; n < arguments . length ; n ++ ) { for ( t in arguments [ n ] ) { e [ t ] = arguments [ n ] [ t ] } } return e } ; a . defaults = { Delay : 150 , EmptyMessage : "No result here" , Highlight : { getRegex : function ( e ) { return new RegExp ( e , "ig" ) } , transform : function ( e ) { return "<strong>" + e + "</strong>" } } , HttpHeaders : { "Content-type" : "application/x-www-form-urlencoded" } , Limit : 0 , MinChars : 0 , HttpMethod : "GET" , QueryArg : "q" , Url : null , KeyboardMappings : { Enter : { Conditions : [ { Is : 13 , Not : false } ] , Callback : function ( e ) { if ( this . DOMResults . getAttribute ( "class" ) . indexOf ( "open" ) != - 1 ) { var t = this . DOMResults . querySelector ( "li.active" ) ; if ( t !== null ) { e . preventDefault ( ) ; this . _Select ( t ) ; this . DOMResults . setAttribute ( "class" , "autocomplete" ) } } } , Operator : l . AND , Event : i . KEYDOWN } , KeyUpAndDown _down : { Conditions : [ { Is : 38 , Not : false } , { Is : 40 , Not : false } ] , Callback : function ( e ) { e . preventDefault ( ) } , Operator : l . OR , Event : i . KEYDOWN } , KeyUpAndDown _up : { Conditions : [ { Is : 38 , Not : false } , { Is : 40 , Not : false } ] , Callback : function ( e ) { e . preventDefault ( ) ; var t = this . DOMResults . querySelector ( "li:first-child:not(.locked)" ) , n = this . DOMResults . querySelector ( "li:last-child:not(.locked)" ) , r = this . DOMResults . querySelector ( "li.active" ) ; if ( r ) { var o = Array . prototype . indexOf . call ( r . parentNode . children , r ) , i = o + ( e . keyCode - 39 ) , s = this . DOMResults . getElementsByTagName ( "li" ) . length ; if ( i < 0 ) { i = s - 1 } else if ( i >= s ) { i = 0 } r . classList . remove ( "active" ) ; r . parentElement . children . item ( i ) . classList . add ( "active" ) } else if ( n && e . keyCode == 38 ) { n . classList . add ( "active" ) } else if ( t ) { t . classList . add ( "active" ) } } , Operator : l . OR , Event : i . KEYUP } , AlphaNum : { Conditions : [ { Is : 13 , Not : true } , { From : 35 , To : 40 , Not : true } ] , Callback : function ( ) { var e = this . Input . getAttribute ( "data-autocomplete-old-value" ) , t = this . _Pre ( ) ; if ( t !== "" && t . length >= this . _MinChars ( ) ) { if ( ! e || t != e ) { this . DOMResults . setAttribute ( "class" , "autocomplete open" ) } a . prototype . cache ( this , function ( e ) { this . _Render ( this . _Post ( e ) ) ; this . _Open ( ) } . bind ( this ) , this . _Error ) } else { this . _Close ( ) } } , Operator : l . AND , Event : i . KEYUP } } , DOMResults : null , Request : null , Input : null , _EmptyMessage : function ( ) { var e = "" ; if ( this . Input . hasAttribute ( "data-autocomplete-empty-message" ) ) { e = this . Input . getAttribute ( "data-autocomplete-empty-message" ) } else if ( this . EmptyMessage !== false ) { e = this . EmptyMessage } else { e = "" } return e } , _Limit : function ( ) { var e = this . Input . getAttribute ( "data-autocomplete-limit" ) ; if ( isNaN ( e ) || e === null ) { return this . Limit } return parseInt ( e , 10 ) } , _MinChars : function ( ) { var e = this . Input . getAttribute ( "data-autocomplete-minchars" ) ; if ( isNaN ( e ) || e === null ) { return this . MinChars } return parseInt ( e , 10 ) } , _Highlight : function ( e ) { return e . replace ( this . Highlight . getRegex ( this . _Pre ( ) ) , this . Highlight . transform ) } , _HttpMethod : function ( ) { if ( this . Input . hasAttribute ( "data-autocomplete-method" ) ) { return this . Input . getAttribute ( "data-autocomplete-method" ) } return this . HttpMethod } , _QueryArg : function ( ) { if ( this . Input . hasAttribute ( "data-autocomplete-param-name" ) ) { return this . Input . getAttribute ( "data-autocomplete-param-name" ) } return this . QueryArg } , _Url : function ( ) { if ( this . Input . hasAttribute ( "data-autocomplete" ) ) { return this . Input . getAttribute ( "data-autocomplete" ) } return this . Url } , _Blur : function ( e ) { if ( e === void 0 ) { e = false } if ( e ) { this . _Close ( ) } else { var t = this ; setTimeout ( function ( ) { t . _Blur ( true ) } , 150 ) } } , _Cache : function ( e ) { return this . $Cache [ e ] } , _Focus : function ( ) { var e = this . Input . getAttribute ( "data-autocomplete-old-value" ) ; if ( ( ! e || this . Input . value != e ) && this . _MinChars ( ) <= this . Input . value . length ) { this . DOMResults . setAttribute ( "class" , "autocomplete open" ) } } , _Open : function ( ) { var t = this ; Array . prototype . forEach . call ( this . DOMResults . getElementsByTagName ( "li" ) , function ( e ) { if ( e . getAttribute ( "class" ) != "locked" ) { e . onclick = function ( ) { t . _Select ( e ) } } } ) } , _Close : function ( ) { this . DOMResults . setAttribute ( "class" , "autocomplete" ) } , _Position : function ( ) { this . DOMResults . setAttribute ( "class" , "autocomplete" ) ; this . DOMResults . setAttribute ( "style" , "top:" + ( this . Input . offsetTop + this . Input . offsetHeight ) + "px;left:" + this . Input . offsetLeft + "px;width:" + this . Input . clientWidth + "px;" ) } , _Render : function ( e ) { var t ; if ( typeof e == "string" ) { t = this . _RenderRaw ( e ) } else { t = this . _RenderResponseItems ( e ) } if ( this . DOMResults . hasChildNodes ( ) ) { this . DOMResults . removeChild ( this . DOMResults . childNodes [ 0 ] ) } this . DOMResults . appendChild ( t ) } , _RenderResponseItems : function ( e ) { var t = document . createElement ( "ul" ) , n = document . createElement ( "li" ) , r = this . _Limit ( ) ; if ( r < 0 ) { e = e . reverse ( ) } else if ( r === 0 ) { r = e . length } for ( var o = 0 ; o < Math . min ( Math . abs ( r ) , e . length ) ; o ++ ) { n . innerHTML = e [ o ] . Label ; n . setAttribute ( "data-autocomplete-value" , e [ o ] . Value ) ; t . appendChild ( n ) ; n = document . createElement ( "li" ) } return t } , _RenderRaw : function ( e ) { var t = document . createElement ( "ul" ) , n = document . createElement ( "li" ) ; if ( e . length > 0 ) { this . DOMResults . innerHTML = e } else { var r = this . _EmptyMessage ( ) ; if ( r !== "" ) { n . innerHTML = r ; n . setAttribute ( "class" , "locked" ) ; t . appendChild ( n ) } } return t } , _Post : function ( t ) { try { var e = [ ] ; var n = JSON . parse ( t ) ; if ( Object . keys ( n ) . length === 0 ) { return "" } if ( Array . isArray ( n ) ) { for ( var r = 0 ; r < Object . keys ( n ) . length ; r ++ ) { e [ e . length ] = { Value : n [ r ] , Label : this . _Highlight ( n [ r ] ) } } } else { for ( var o in n ) { e . push ( { Value : o , Label : this . _Highlight ( n [ o ] ) } ) } } return e } catch ( e ) { return t } } , _Pre : function ( ) { return this . Input . value } , _Select : function ( e ) { if ( e . hasAttribute ( "data-autocomplete-value" ) ) { this . Input . value = e . getAttribute ( "data-autocomplete-value" ) } else { this . Input . value = e . innerHTML } this . Input . setAttribute ( "data-autocomplete-old-value" , this . Input . value ) } , _Error : function ( ) { } , $AjaxTimer : null , $Cache : { } , $Listeners : { } } ; return a } ( ) ; t . exports = r } , { } ] } , { } , [ 1 ] ) ( 1 ) } ) ;