diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..06280f7 --- /dev/null +++ b/METADATA @@ -0,0 +1,2 @@ +languages: bash, css, json, lisp, markdown, plaintext, xml, yaml +theme: a11y-dark diff --git a/changelog.xml b/changelog.xml new file mode 100644 index 0000000..b83f5a5 --- /dev/null +++ b/changelog.xml @@ -0,0 +1,123 @@ + + + + log4cl-extras ChangeLog + https://40ants.com/log4cl-extras/ + xml-emitter + en-us + + 0.11.0 (2024-03-01) + <h1 id="changed">Changed</h1><p>Macro <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a> now handles <code>SERIOUS-CONDITION</code> instead of <code>ERROR</code>. This is important, because <code>ERROR</code> is not a only subclass of the <code>SERIOUS-CONDITION</code>, for example, <code>SB-EXT:TIMEOUT</code> is inherited directly from <code>SERIOUS-CONDITION</code> and old version of the macro was not able to log such errors.</p> + Fri, 01 Mar 2024 00:00:00 +0000 + + + 0.10.0 (2023-11-19) + <h1 id="new">New</h1><p>Variable <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3A-2ADEBUG-ON-ERROR-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FAPPENDERS-3A-2ADEBUG-ON-ERROR-2A-20-28VARIABLE-29-29"><code>log4cl-extras/appenders:*debug-on-error*</code></a> was added and can be used to debug issues happening when handling log messages. +When this option is <code>NIL</code>, appenders defined in log4cl-extras will only output &quot;Unable to log the message&quot; message in case of errors +during the message output.</p><h1 id="fixes">Fixes</h1><ul><li><p>Package log4cl-extras now is created when library is loaded. This should fix a warning from <code>ASDF</code> about missing package.</p></li></ul> + Sun, 19 Nov 2023 00:00:00 +0000 + + + 0.9.0 (2022-12-30) + <p>Function <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29"><code>log4cl-extras/error:print-backtrace</code></a> now prints conditions with type like:</p><pre><code class="">Condition REBLOCKS-WEBSOCKET:NO-ACTIVE-WEBSOCKETS: No active websockets bound to the current page.</code></pre><p>instead of:</p><p>Condition: No active websockets bound to the current page.</p> + Fri, 30 Dec 2022 00:00:00 +0000 + + + 0.8.0 (2022-11-04) + <ul><li><p>Macro <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a> now has <code>ERRORS-TO-IGNORE</code> argument. +You can pass a list of class-names of conditions which should not be logged.</p></li></ul> + Fri, 04 Nov 2022 00:00:00 +0000 + + + 0.7.2 (2022-10-03) + <ul><li><p>Backtrace printer was fixed to work on Clozure<code>CL</code>.</p></li></ul> + Mon, 03 Oct 2022 00:00:00 +0000 + + + 0.7.1 (2022-08-06) + <ul><li><p>Now <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29"><code>log4cl-extras/secrets:make-secrets-replacer</code></a> is able to mask secret values even in strings nested in the lists. + This fixes issue of leaking Authorization tokens when some <code>HTTP</code> error is logged.</p><p>Previously, backtrace was logged like this:</p><pre><code class="">1 File &quot;/Users/art/projects/lisp/cloud-analyzer/.qlot/dists/ultralisp/software/fukamachi-dexador-20220619102143/src/backend/usocket.lisp&quot;, line 451 + In DEXADOR.BACKEND.USOCKET:REQUEST + Args (#&lt;unavailable argument&gt; :METHOD :GET :HEADERS ((&quot;Authorization&quot; . &quot;OAuth AQAEA5qgMKaqAAffdZ0Nw7BqTkCTlp6ii80Gdmo&quot;)))</code></pre><p>and oauth token leaked to the log storage.</p><p>After this fix, backtrace will be logged like this:</p><pre><code class="">1 File &quot;/Users/art/projects/lisp/cloud-analyzer/.qlot/dists/ultralisp/software/fukamachi-dexador-20220619102143/src/backend/usocket.lisp&quot;, line 451 + In DEXADOR.BACKEND.USOCKET:REQUEST + Args (#&lt;unavailable argument&gt; :METHOD :GET :HEADERS ((&quot;Authorization&quot; . &quot;OAuth #&lt;secret value&gt;&quot;)))</code></pre></li><li><p>A new variable <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*args-filter-constructors*</code></a> was introduced. It should be used together + with <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29"><code>log4cl-extras/secrets:make-secrets-replacer</code></a> to prevent secrets collection during the program life.</p><p>Previosly, when you created a secrets replaced and stored in in the <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTERS-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTERS-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*args-filters*</code></a> variable, +all secrets from logged backtraces were collected in a closure's state. When +<a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*args-filter-constructors*</code></a> variable is used, a new secrets replacer will be created +for processing of each backtrace.</p></li></ul> + Sat, 06 Aug 2022 00:00:00 +0000 + + + 0.7.0 (2022-07-03) + <ul><li><p>Macro <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a> now uses internal function and you can change backtrace length on the fly by changing <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*max-traceback-depth*</code></a> variable.</p></li><li><p>Also, <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*max-call-length*</code></a> variable was documented.</p></li></ul> + Sun, 03 Jul 2022 00:00:00 +0000 + + + 0.6.0 (2021-10-03) + <ul><li><p>Now <code>:PLAIN</code> and <code>:JSON</code> logger will output logger's category, filename and a callable name.</p></li></ul> + Sun, 03 Oct 2021 00:00:00 +0000 + + + 0.5.1 (2021-03-02) + <ul><li><p>Fixed fail during logging error with <code>(setf some-func)</code> in the backtrace.</p></li></ul> + Tue, 02 Mar 2021 00:00:00 +0000 + + + 0.5.0 (2021-01-24) + <ul><li><p>Function <code>TRACEBACK-TO-STRING</code> was removed and + replaced with <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29"><code>log4cl-extras/error:print-backtrace</code></a> which is now + a part of public <code>API</code>.</p></li><li><p>Added ability to filter secret and sensitive values. + Read documentation, to lear more.</p></li></ul> + Sun, 24 Jan 2021 00:00:00 +0000 + + + 0.4.2 (2020-11-26) + <h1 id="fixed">Fixed</h1><ul><li><p>Fixed <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>with-log-unhandled</code></a> for cases when some function argument's print-object signaled the error.</p></li></ul><p>Because of this nasty error, sometimes <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>with-log-unhandled</code></a> didn't log &quot;Unandled error&quot;.</p><h1 id="added">Added</h1><ul><li><p>Now <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a> macro accepts key argument <code>DEPTH</code> which is 10 by default.</p></li></ul><p>This argument can be overriden by setting <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*max-traceback-depth*</code></a>.</p><ul><li><p>Also another variable <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29"><code>log4cl-extras/error:*max-call-length*</code></a> can be set to control + how long function or method name can be. By default it is 100, but methods are logged along + with their specialized arguments and can be longer.</p></li></ul> + Thu, 26 Nov 2020 00:00:00 +0000 + + + 0.4.1 (2019-03-05) + <h1 id="fixed">Fixed</h1><ul><li><p>Added missing dependency from <code>CL-STRINGS</code> system.</p></li></ul> + Tue, 05 Mar 2019 00:00:00 +0000 + + + 0.4.0 (2019-03-04) + <h1 id="improved">Improved</h1><p>Now <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONFIG-3ASETUP-20FUNCTION-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FCONFIG-3ASETUP-20FUNCTION-29"><code>log4cl-extras/config:setup</code></a> sets appender into a mode when it prints log in a human +readable way if it its called from the <code>SLY</code>'s <code>REPL</code>. All logger fields are +printed as well, including a traceback.</p> + Mon, 04 Mar 2019 00:00:00 +0000 + + + 0.3.0 (2019-01-07) + <h1 id="improved">Improved</h1><ul><li><p>Now condition's description is added to the end of the backtrace.</p></li></ul> + Mon, 07 Jan 2019 00:00:00 +0000 + + + 0.2.2 (2018-12-08) + <h1 id="fixed">Fixed</h1><ul><li><p>Fixed system's loading in environments with <code>C</code> locale.</p></li></ul><p>This closes issue reported along with pull request #1.</p> + Sat, 08 Dec 2018 00:00:00 +0000 + + + 0.2.1 (2018-11-24) + <h1 id="fixed">Fixed</h1><ul><li><p>Previously, macros <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a> catched every signal, + not only signals derived from <code>ERROR</code>. Because of that, + it logged traceback for non error signals like that:</p></li></ul><p><code>lisp + (log4cl-json/error:with-log-unhandled () + (signal &quot;foo&quot;)) +</code></p><p>Now this bad behavior was fixed and only <code>errors</code> are logged.</p> + Sat, 24 Nov 2018 00:00:00 +0000 + + + 0.2.0 (2017-08-29) + <h1 id="new">New</h1><ul><li><p>Added ability to log tracebacks using <a href="https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29" data-document="https://40ants.com/log4cl-extras/" data-node="x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"><code>log4cl-extras/error:with-log-unhandled</code></a>.</p></li></ul> + Tue, 29 Aug 2017 00:00:00 +0000 + + + 0.1.0 (2017-01-23) + <ul><li><p>Initial version.</p></li></ul> + Mon, 23 Jan 2017 00:00:00 +0000 + + + \ No newline at end of file diff --git a/changelog/index.html b/changelog/index.html new file mode 100644 index 0000000..e8b2257 --- /dev/null +++ b/changelog/index.html @@ -0,0 +1,147 @@ + + + + ChangeLog + + + + + + + + + + + + +
Fork me on GitHub + + +

ChangeLog

0.11.0 (2024-03-01)

Changed

Macro log4cl-extras/error:with-log-unhandled now handles SERIOUS-CONDITION instead of ERROR. This is important, because ERROR is not a only subclass of the SERIOUS-CONDITION, for example, SB-EXT:TIMEOUT is inherited directly from SERIOUS-CONDITION and old version of the macro was not able to log such errors.

0.10.0 (2023-11-19)

New

Variable log4cl-extras/appenders:*debug-on-error* was added and can be used to debug issues happening when handling log messages. +When this option is NIL, appenders defined in log4cl-extras will only output "Unable to log the message" message in case of errors +during the message output.

Fixes

0.9.0 (2022-12-30)

Function log4cl-extras/error:print-backtrace now prints conditions with type like:

Condition REBLOCKS-WEBSOCKET:NO-ACTIVE-WEBSOCKETS: No active websockets bound to the current page.

instead of:

Condition: No active websockets bound to the current page.

0.8.0 (2022-11-04)

0.7.2 (2022-10-03)

0.7.1 (2022-08-06)

0.7.0 (2022-07-03)

0.6.0 (2021-10-03)

0.5.1 (2021-03-02)

0.5.0 (2021-01-24)

0.4.2 (2020-11-26)

Fixed

Because of this nasty error, sometimes with-log-unhandled didn't log "Unandled error".

Added

This argument can be overriden by setting log4cl-extras/error:*max-traceback-depth*.

0.4.1 (2019-03-05)

Fixed

0.4.0 (2019-03-04)

Improved

Now log4cl-extras/config:setup sets appender into a mode when it prints log in a human +readable way if it its called from the SLY's REPL. All logger fields are +printed as well, including a traceback.

0.3.0 (2019-01-07)

Improved

0.2.2 (2018-12-08)

Fixed

This closes issue reported along with pull request #1.

0.2.1 (2018-11-24)

Fixed

lisp + (log4cl-json/error:with-log-unhandled () + (signal "foo")) +

Now this bad behavior was fixed and only errors are logged.

0.2.0 (2017-08-29)

New

0.1.0 (2017-01-23)

+
+
+ + \ No newline at end of file diff --git a/doctools.js b/doctools.js new file mode 100644 index 0000000..8cbf1b1 --- /dev/null +++ b/doctools.js @@ -0,0 +1,323 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/highlight.min.css b/highlight.min.css new file mode 100644 index 0000000..7820d7d --- /dev/null +++ b/highlight.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: a11y-dark + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/.hljs{background:#2b2b2b;color:#f8f8f2}.hljs-comment,.hljs-quote{color:#d4d0ab}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ffa07a}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5ab35}.hljs-attribute{color:gold}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#abe338}.hljs-section,.hljs-title{color:#00e0e0}.hljs-keyword,.hljs-selector-tag{color:#dcc6e0}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}} \ No newline at end of file diff --git a/highlight.min.js b/highlight.min.js new file mode 100644 index 0000000..d14eb0c --- /dev/null +++ b/highlight.min.js @@ -0,0 +1,466 @@ +/*! + Highlight.js v11.9.0 (git: b7ec4bfafc) + (c) 2006-2023 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(t){ +return t instanceof Map?t.clear=t.delete=t.set=()=>{ +throw Error("map is read-only")}:t instanceof Set&&(t.add=t.clear=t.delete=()=>{ +throw Error("set is read-only") +}),Object.freeze(t),Object.getOwnPropertyNames(t).forEach((n=>{ +const i=t[n],s=typeof i;"object"!==s&&"function"!==s||Object.isFrozen(i)||e(i) +})),t}class t{constructor(e){ +void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} +ignoreMatch(){this.isMatchIgnored=!0}}function n(e){ +return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") +}function i(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t] +;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}const s=e=>!!e.scope +;class o{constructor(e,t){ +this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){ +this.buffer+=n(e)}openNode(e){if(!s(e))return;const t=((e,{prefix:t})=>{ +if(e.startsWith("language:"))return e.replace("language:","language-") +;if(e.includes(".")){const n=e.split(".") +;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ") +}return`${t}${e}`})(e.scope,{prefix:this.classPrefix});this.span(t)} +closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ +this.buffer+=``}}const r=(e={})=>{const t={children:[]} +;return Object.assign(t,e),t};class a{constructor(){ +this.rootNode=r(),this.stack=[this.rootNode]}get top(){ +return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ +this.top.children.push(e)}openNode(e){const t=r({scope:e}) +;this.add(t),this.stack.push(t)}closeNode(){ +if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ +for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} +walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){ +return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t), +t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){ +"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ +a._collapse(e)})))}}class c extends a{constructor(e){super(),this.options=e} +addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ +this.closeNode()}__addSublanguage(e,t){const n=e.root +;t&&(n.scope="language:"+t),this.add(n)}toHTML(){ +return new o(this,this.options).value()}finalize(){ +return this.closeAllNodes(),!0}}function l(e){ +return e?"string"==typeof e?e:e.source:null}function g(e){return h("(?=",e,")")} +function u(e){return h("(?:",e,")*")}function d(e){return h("(?:",e,")?")} +function h(...e){return e.map((e=>l(e))).join("")}function f(...e){const t=(e=>{ +const t=e[e.length-1] +;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{} +})(e);return"("+(t.capture?"":"?:")+e.map((e=>l(e))).join("|")+")"} +function p(e){return RegExp(e.toString()+"|").exec("").length-1} +const b=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ +;function m(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n +;let i=l(e),s="";for(;i.length>0;){const e=b.exec(i);if(!e){s+=i;break} +s+=i.substring(0,e.index), +i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?s+="\\"+(Number(e[1])+t):(s+=e[0], +"("===e[0]&&n++)}return s})).map((e=>`(${e})`)).join(t)} +const E="[a-zA-Z]\\w*",x="[a-zA-Z_]\\w*",w="\\b\\d+(\\.\\d+)?",y="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",_="\\b(0b[01]+)",O={ +begin:"\\\\[\\s\\S]",relevance:0},v={scope:"string",begin:"'",end:"'", +illegal:"\\n",contains:[O]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", +contains:[O]},N=(e,t,n={})=>{const s=i({scope:"comment",begin:e,end:t, +contains:[]},n);s.contains.push({scope:"doctag", +begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", +end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) +;const o=f("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) +;return s.contains.push({begin:h(/[ ]+/,"(",o,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),s +},S=N("//","$"),M=N("/\\*","\\*/"),R=N("#","$");var j=Object.freeze({ +__proto__:null,APOS_STRING_MODE:v,BACKSLASH_ESCAPE:O,BINARY_NUMBER_MODE:{ +scope:"number",begin:_,relevance:0},BINARY_NUMBER_RE:_,COMMENT:N, +C_BLOCK_COMMENT_MODE:M,C_LINE_COMMENT_MODE:S,C_NUMBER_MODE:{scope:"number", +begin:y,relevance:0},C_NUMBER_RE:y,END_SAME_AS_BEGIN:e=>Object.assign(e,{ +"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{ +t.data._beginMatch!==e[1]&&t.ignoreMatch()}}),HASH_COMMENT_MODE:R,IDENT_RE:E, +MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+x,relevance:0}, +NUMBER_MODE:{scope:"number",begin:w,relevance:0},NUMBER_RE:w, +PHRASAL_WORDS_MODE:{ +begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ +},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, +end:/\/[gimuy]*/,contains:[O,{begin:/\[/,end:/\]/,relevance:0,contains:[O]}]}, +RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", +SHEBANG:(e={})=>{const t=/^#![ ]*\// +;return e.binary&&(e.begin=h(t,/.*\b/,e.binary,/\b.*/)),i({scope:"meta",begin:t, +end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)}, +TITLE_MODE:{scope:"title",begin:E,relevance:0},UNDERSCORE_IDENT_RE:x, +UNDERSCORE_TITLE_MODE:{scope:"title",begin:x,relevance:0}});function A(e,t){ +"."===e.input[e.index-1]&&t.ignoreMatch()}function I(e,t){ +void 0!==e.className&&(e.scope=e.className,delete e.className)}function T(e,t){ +t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", +e.__beforeBegin=A,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, +void 0===e.relevance&&(e.relevance=0))}function L(e,t){ +Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function B(e,t){ +if(e.match){ +if(e.begin||e.end)throw Error("begin & end are not supported with match") +;e.begin=e.match,delete e.match}}function P(e,t){ +void 0===e.relevance&&(e.relevance=1)}const D=(e,t)=>{if(!e.beforeMatch)return +;if(e.starts)throw Error("beforeMatch cannot be used with starts") +;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t] +})),e.keywords=n.keywords,e.begin=h(n.beforeMatch,g(n.begin)),e.starts={ +relevance:0,contains:[Object.assign(n,{endsParent:!0})] +},e.relevance=0,delete n.beforeMatch +},H=["of","and","for","in","not","or","if","then","parent","list","value"],C="keyword" +;function $(e,t,n=C){const i=Object.create(null) +;return"string"==typeof e?s(n,e.split(" ")):Array.isArray(e)?s(n,e):Object.keys(e).forEach((n=>{ +Object.assign(i,$(e[n],t,n))})),i;function s(e,n){ +t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|") +;i[n[0]]=[e,U(n[0],n[1])]}))}}function U(e,t){ +return t?Number(t):(e=>H.includes(e.toLowerCase()))(e)?0:1}const z={},W=e=>{ +console.error(e)},X=(e,...t)=>{console.log("WARN: "+e,...t)},G=(e,t)=>{ +z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),z[`${e}/${t}`]=!0) +},K=Error();function F(e,t,{key:n}){let i=0;const s=e[n],o={},r={} +;for(let e=1;e<=t.length;e++)r[e+i]=s[e],o[e+i]=!0,i+=p(t[e-1]) +;e[n]=r,e[n]._emit=o,e[n]._multi=!0}function Z(e){(e=>{ +e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, +delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ +_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope +}),(e=>{if(Array.isArray(e.begin)){ +if(e.skip||e.excludeBegin||e.returnBegin)throw W("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), +K +;if("object"!=typeof e.beginScope||null===e.beginScope)throw W("beginScope must be object"), +K;F(e,e.begin,{key:"beginScope"}),e.begin=m(e.begin,{joinWith:""})}})(e),(e=>{ +if(Array.isArray(e.end)){ +if(e.skip||e.excludeEnd||e.returnEnd)throw W("skip, excludeEnd, returnEnd not compatible with endScope: {}"), +K +;if("object"!=typeof e.endScope||null===e.endScope)throw W("endScope must be object"), +K;F(e,e.end,{key:"endScope"}),e.end=m(e.end,{joinWith:""})}})(e)}function V(e){ +function t(t,n){ +return RegExp(l(t),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(n?"g":"")) +}class n{constructor(){ +this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} +addRule(e,t){ +t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]), +this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) +;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(m(e,{joinWith:"|" +}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex +;const t=this.matcherRe.exec(e);if(!t)return null +;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n] +;return t.splice(0,n),Object.assign(t,i)}}class s{constructor(){ +this.rules=[],this.multiRegexes=[], +this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ +if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n +;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))), +t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){ +return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){ +this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){ +const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex +;let n=t.exec(e) +;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{ +const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)} +return n&&(this.regexIndex+=n.position+1, +this.regexIndex===this.count&&this.considerAll()),n}} +if(e.compilerExtensions||(e.compilerExtensions=[]), +e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") +;return e.classNameAliases=i(e.classNameAliases||{}),function n(o,r){const a=o +;if(o.isCompiled)return a +;[I,B,Z,D].forEach((e=>e(o,r))),e.compilerExtensions.forEach((e=>e(o,r))), +o.__beforeBegin=null,[T,L,P].forEach((e=>e(o,r))),o.isCompiled=!0;let c=null +;return"object"==typeof o.keywords&&o.keywords.$pattern&&(o.keywords=Object.assign({},o.keywords), +c=o.keywords.$pattern, +delete o.keywords.$pattern),c=c||/\w+/,o.keywords&&(o.keywords=$(o.keywords,e.case_insensitive)), +a.keywordPatternRe=t(c,!0), +r&&(o.begin||(o.begin=/\B|\b/),a.beginRe=t(a.begin),o.end||o.endsWithParent||(o.end=/\B|\b/), +o.end&&(a.endRe=t(a.end)), +a.terminatorEnd=l(a.end)||"",o.endsWithParent&&r.terminatorEnd&&(a.terminatorEnd+=(o.end?"|":"")+r.terminatorEnd)), +o.illegal&&(a.illegalRe=t(o.illegal)), +o.contains||(o.contains=[]),o.contains=[].concat(...o.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>i(e,{ +variants:null},t)))),e.cachedVariants?e.cachedVariants:q(e)?i(e,{ +starts:e.starts?i(e.starts):null +}):Object.isFrozen(e)?i(e):e))("self"===e?o:e)))),o.contains.forEach((e=>{n(e,a) +})),o.starts&&n(o.starts,r),a.matcher=(e=>{const t=new s +;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin" +}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end" +}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function q(e){ +return!!e&&(e.endsWithParent||q(e.starts))}class J extends Error{ +constructor(e,t){super(e),this.name="HTMLInjectionError",this.html=t}} +const Y=n,Q=i,ee=Symbol("nomatch"),te=n=>{ +const i=Object.create(null),s=Object.create(null),o=[];let r=!0 +;const a="Could not find the language '{}', did you forget to load/include a language module?",l={ +disableAutodetect:!0,name:"Plain text",contains:[]};let p={ +ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, +languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", +cssSelector:"pre code",languages:null,__emitter:c};function b(e){ +return p.noHighlightRe.test(e)}function m(e,t,n){let i="",s="" +;"object"==typeof t?(i=e, +n=t.ignoreIllegals,s=t.language):(G("10.7.0","highlight(lang, code, ...args) has been deprecated."), +G("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), +s=e,i=t),void 0===n&&(n=!0);const o={code:i,language:s};N("before:highlight",o) +;const r=o.result?o.result:E(o.language,o.code,n) +;return r.code=o.code,N("after:highlight",r),r}function E(e,n,s,o){ +const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(R) +;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(R),n="" +;for(;t;){n+=R.substring(e,t.index) +;const s=_.case_insensitive?t[0].toLowerCase():t[0],o=(i=s,N.keywords[i]);if(o){ +const[e,i]=o +;if(M.addText(n),n="",c[s]=(c[s]||0)+1,c[s]<=7&&(j+=i),e.startsWith("_"))n+=t[0];else{ +const n=_.classNameAliases[e]||e;u(t[0],n)}}else n+=t[0] +;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(R)}var i +;n+=R.substring(e),M.addText(n)}function g(){null!=N.subLanguage?(()=>{ +if(""===R)return;let e=null;if("string"==typeof N.subLanguage){ +if(!i[N.subLanguage])return void M.addText(R) +;e=E(N.subLanguage,R,!0,S[N.subLanguage]),S[N.subLanguage]=e._top +}else e=x(R,N.subLanguage.length?N.subLanguage:null) +;N.relevance>0&&(j+=e.relevance),M.__addSublanguage(e._emitter,e.language) +})():l(),R=""}function u(e,t){ +""!==e&&(M.startScope(t),M.addText(e),M.endScope())}function d(e,t){let n=1 +;const i=t.length-1;for(;n<=i;){if(!e._emit[n]){n++;continue} +const i=_.classNameAliases[e[n]]||e[n],s=t[n];i?u(s,i):(R=s,l(),R=""),n++}} +function h(e,t){ +return e.scope&&"string"==typeof e.scope&&M.openNode(_.classNameAliases[e.scope]||e.scope), +e.beginScope&&(e.beginScope._wrap?(u(R,_.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), +R=""):e.beginScope._multi&&(d(e.beginScope,t),R="")),N=Object.create(e,{parent:{ +value:N}}),N}function f(e,n,i){let s=((e,t)=>{const n=e&&e.exec(t) +;return n&&0===n.index})(e.endRe,i);if(s){if(e["on:end"]){const i=new t(e) +;e["on:end"](n,i),i.isMatchIgnored&&(s=!1)}if(s){ +for(;e.endsParent&&e.parent;)e=e.parent;return e}} +if(e.endsWithParent)return f(e.parent,n,i)}function b(e){ +return 0===N.matcher.regexIndex?(R+=e[0],1):(T=!0,0)}function m(e){ +const t=e[0],i=n.substring(e.index),s=f(N,e,i);if(!s)return ee;const o=N +;N.endScope&&N.endScope._wrap?(g(), +u(t,N.endScope._wrap)):N.endScope&&N.endScope._multi?(g(), +d(N.endScope,e)):o.skip?R+=t:(o.returnEnd||o.excludeEnd||(R+=t), +g(),o.excludeEnd&&(R=t));do{ +N.scope&&M.closeNode(),N.skip||N.subLanguage||(j+=N.relevance),N=N.parent +}while(N!==s.parent);return s.starts&&h(s.starts,e),o.returnEnd?0:t.length} +let w={};function y(i,o){const a=o&&o[0];if(R+=i,null==a)return g(),0 +;if("begin"===w.type&&"end"===o.type&&w.index===o.index&&""===a){ +if(R+=n.slice(o.index,o.index+1),!r){const t=Error(`0 width match regex (${e})`) +;throw t.languageName=e,t.badRule=w.rule,t}return 1} +if(w=o,"begin"===o.type)return(e=>{ +const n=e[0],i=e.rule,s=new t(i),o=[i.__beforeBegin,i["on:begin"]] +;for(const t of o)if(t&&(t(e,s),s.isMatchIgnored))return b(n) +;return i.skip?R+=n:(i.excludeBegin&&(R+=n), +g(),i.returnBegin||i.excludeBegin||(R=n)),h(i,e),i.returnBegin?0:n.length})(o) +;if("illegal"===o.type&&!s){ +const e=Error('Illegal lexeme "'+a+'" for mode "'+(N.scope||"")+'"') +;throw e.mode=N,e}if("end"===o.type){const e=m(o);if(e!==ee)return e} +if("illegal"===o.type&&""===a)return 1 +;if(I>1e5&&I>3*o.index)throw Error("potential infinite loop, way more iterations than matches") +;return R+=a,a.length}const _=O(e) +;if(!_)throw W(a.replace("{}",e)),Error('Unknown language: "'+e+'"') +;const v=V(_);let k="",N=o||v;const S={},M=new p.__emitter(p);(()=>{const e=[] +;for(let t=N;t!==_;t=t.parent)t.scope&&e.unshift(t.scope) +;e.forEach((e=>M.openNode(e)))})();let R="",j=0,A=0,I=0,T=!1;try{ +if(_.__emitTokens)_.__emitTokens(n,M);else{for(N.matcher.considerAll();;){ +I++,T?T=!1:N.matcher.considerAll(),N.matcher.lastIndex=A +;const e=N.matcher.exec(n);if(!e)break;const t=y(n.substring(A,e.index),e) +;A=e.index+t}y(n.substring(A))}return M.finalize(),k=M.toHTML(),{language:e, +value:k,relevance:j,illegal:!1,_emitter:M,_top:N}}catch(t){ +if(t.message&&t.message.includes("Illegal"))return{language:e,value:Y(n), +illegal:!0,relevance:0,_illegalBy:{message:t.message,index:A, +context:n.slice(A-100,A+100),mode:t.mode,resultSoFar:k},_emitter:M};if(r)return{ +language:e,value:Y(n),illegal:!1,relevance:0,errorRaised:t,_emitter:M,_top:N} +;throw t}}function x(e,t){t=t||p.languages||Object.keys(i);const n=(e=>{ +const t={value:Y(e),illegal:!1,relevance:0,_top:l,_emitter:new p.__emitter(p)} +;return t._emitter.addText(e),t})(e),s=t.filter(O).filter(k).map((t=>E(t,e,!1))) +;s.unshift(n);const o=s.sort(((e,t)=>{ +if(e.relevance!==t.relevance)return t.relevance-e.relevance +;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1 +;if(O(t.language).supersetOf===e.language)return-1}return 0})),[r,a]=o,c=r +;return c.secondBest=a,c}function w(e){let t=null;const n=(e=>{ +let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"" +;const n=p.languageDetectRe.exec(t);if(n){const t=O(n[1]) +;return t||(X(a.replace("{}",n[1])), +X("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"} +return t.split(/\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return +;if(N("before:highlightElement",{el:e,language:n +}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) +;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), +console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), +console.warn("The element with unescaped HTML:"), +console.warn(e)),p.throwUnescapedHTML))throw new J("One of your code blocks includes unescaped HTML.",e.innerHTML) +;t=e;const i=t.textContent,o=n?m(i,{language:n,ignoreIllegals:!0}):x(i) +;e.innerHTML=o.value,e.dataset.highlighted="yes",((e,t,n)=>{const i=t&&s[t]||n +;e.classList.add("hljs"),e.classList.add("language-"+i) +})(e,n,o.language),e.result={language:o.language,re:o.relevance, +relevance:o.relevance},o.secondBest&&(e.secondBest={ +language:o.secondBest.language,relevance:o.secondBest.relevance +}),N("after:highlightElement",{el:e,result:o,text:i})}let y=!1;function _(){ +"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(w):y=!0 +}function O(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]} +function v(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ +s[e.toLowerCase()]=t}))}function k(e){const t=O(e) +;return t&&!t.disableAutodetect}function N(e,t){const n=e;o.forEach((e=>{ +e[n]&&e[n](t)}))} +"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ +y&&_()}),!1),Object.assign(n,{highlight:m,highlightAuto:x,highlightAll:_, +highlightElement:w, +highlightBlock:e=>(G("10.7.0","highlightBlock will be removed entirely in v12.0"), +G("10.7.0","Please use highlightElement now."),w(e)),configure:e=>{p=Q(p,e)}, +initHighlighting:()=>{ +_(),G("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, +initHighlightingOnLoad:()=>{ +_(),G("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") +},registerLanguage:(e,t)=>{let s=null;try{s=t(n)}catch(t){ +if(W("Language definition for '{}' could not be registered.".replace("{}",e)), +!r)throw t;W(t),s=l} +s.name||(s.name=e),i[e]=s,s.rawDefinition=t.bind(null,n),s.aliases&&v(s.aliases,{ +languageName:e})},unregisterLanguage:e=>{delete i[e] +;for(const t of Object.keys(s))s[t]===e&&delete s[t]}, +listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v, +autoDetection:k,inherit:Q,addPlugin:e=>{(e=>{ +e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{ +e["before:highlightBlock"](Object.assign({block:t.el},t)) +}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{ +e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),o.push(e)}, +removePlugin:e=>{const t=o.indexOf(e);-1!==t&&o.splice(t,1)}}),n.debugMode=()=>{ +r=!1},n.safeMode=()=>{r=!0},n.versionString="11.9.0",n.regex={concat:h, +lookahead:g,either:f,optional:d,anyNumberOfTimes:u} +;for(const t in j)"object"==typeof j[t]&&e(j[t]);return Object.assign(n,j),n +},ne=te({});return ne.newInstance=()=>te({}),ne}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);/*! `bash` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const s=e.regex,t={},n={begin:/\$\{/, +end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{ +className:"variable",variants:[{ +begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const a={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE] +},i=e.inherit(e.COMMENT(),{match:[/(^|\s)/,/#.*$/],scope:{2:"comment"}}),c={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},o={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,a]};a.contains.push(o);const r={begin:/\$?\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),m={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[l,e.SHEBANG(),m,r,i,c,{match:/(\/[a-z._-]+)+/},o,{match:/\\"/},{ +className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}})() +;hljs.registerLanguage("bash",e)})();/*! `css` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict" +;const e=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video","defs","g","marker","mask","pattern","svg","switch","symbol","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feGaussianBlur","feImage","feMerge","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","linearGradient","radialGradient","stop","circle","ellipse","image","line","path","polygon","polyline","rect","text","use","textPath","tspan","foreignObject","clipPath"],r=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"].sort().reverse(),o=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"].sort().reverse(),t=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"].sort().reverse(),i=["align-content","align-items","align-self","alignment-baseline","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","cx","cy","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","empty-cells","enable-background","fill","fill-opacity","fill-rule","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","flood-color","flood-opacity","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-horizontal","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","kerning","justify-content","left","letter-spacing","lighting-color","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","mask","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","r","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","shape-rendering","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","speak","speak-as","src","tab-size","table-layout","text-anchor","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vector-effect","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","x","y","z-index"].sort().reverse() +;return n=>{const a=n.regex,l=(e=>({IMPORTANT:{scope:"meta",begin:"!important"}, +BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number", +begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{ +className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{ +scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} +}))(n),s=[n.APOS_STRING_MODE,n.QUOTE_STRING_MODE];return{name:"CSS", +case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"}, +classNameAliases:{keyframePosition:"selector-tag"},contains:[l.BLOCK_COMMENT,{ +begin:/-(webkit|moz|ms|o)-(?=[a-z])/},l.CSS_NUMBER_MODE,{ +className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{ +className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 +},l.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ +begin:":("+o.join("|")+")"},{begin:":(:)?("+t.join("|")+")"}]},l.CSS_VARIABLE,{ +className:"attribute",begin:"\\b("+i.join("|")+")\\b"},{begin:/:/,end:/[;}{]/, +contains:[l.BLOCK_COMMENT,l.HEXCOLOR,l.IMPORTANT,l.CSS_NUMBER_MODE,...s,{ +begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" +},contains:[...s,{className:"string",begin:/[^)]/,endsWithParent:!0, +excludeEnd:!0}]},l.FUNCTION_DISPATCH]},{begin:a.lookahead(/@/),end:"[{;]", +relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ +},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ +$pattern:/[a-z-]+/,keyword:"and or not only",attribute:r.join(" ")},contains:[{ +begin:/[a-z-]+(?=:)/,className:"attribute"},...s,l.CSS_NUMBER_MODE]}]},{ +className:"selector-tag",begin:"\\b("+e.join("|")+")\\b"}]}}})() +;hljs.registerLanguage("css",e)})();/*! `json` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const a=["true","false","null"],n={ +scope:"literal",beginKeywords:a.join(" ")};return{name:"JSON",keywords:{ +literal:a},contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/, +relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0 +},e.QUOTE_STRING_MODE,n,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], +illegal:"\\S"}}})();hljs.registerLanguage("json",e)})();/*! `lisp` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n="[a-zA-Z_\\-+\\*\\/<=>&#][a-zA-Z0-9_\\-+*\\/<=>&#!]*",a="\\|[^]*?\\|",i="(-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|-)?\\d+)?",s={ +className:"literal",begin:"\\b(t{1}|nil)\\b"},l={className:"number",variants:[{ +begin:i,relevance:0},{begin:"#(b|B)[0-1]+(/[0-1]+)?"},{ +begin:"#(o|O)[0-7]+(/[0-7]+)?"},{begin:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{ +begin:"#(c|C)\\("+i+" +"+i,end:"\\)"}]},b=e.inherit(e.QUOTE_STRING_MODE,{ +illegal:null}),g=e.COMMENT(";","$",{relevance:0}),r={begin:"\\*",end:"\\*"},t={ +className:"symbol",begin:"[:&]"+n},c={begin:n,relevance:0},d={begin:a},o={ +contains:[l,b,r,t,{begin:"\\(",end:"\\)",contains:["self",s,b,l,c]},c], +variants:[{begin:"['`]\\(",end:"\\)"},{begin:"\\(quote ",end:"\\)",keywords:{ +name:"quote"}},{begin:"'"+a}]},v={variants:[{begin:"'"+n},{ +begin:"#'"+n+"(::"+n+")*"}]},m={begin:"\\(\\s*",end:"\\)"},u={endsWithParent:!0, +relevance:0};return m.contains=[{className:"name",variants:[{begin:n,relevance:0 +},{begin:a}]},u],u.contains=[o,v,m,s,l,b,g,r,t,d,c],{name:"Lisp",illegal:/\S/, +contains:[l,e.SHEBANG(),s,b,g,o,v,m,c]}}})();hljs.registerLanguage("lisp",e) +})();/*! `markdown` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n={begin:/<\/?[A-Za-z_]/, +end:">",subLanguage:"xml",relevance:0},a={variants:[{begin:/\[.+?\]\[.*?\]/, +relevance:0},{ +begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, +relevance:2},{ +begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), +relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ +begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ +},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, +returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", +excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", +end:"\\]",excludeBegin:!0,excludeEnd:!0}]},i={className:"strong",contains:[], +variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] +},s={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ +begin:/_(?![_\s])/,end:/_/,relevance:0}]},c=e.inherit(i,{contains:[] +}),t=e.inherit(s,{contains:[]});i.contains.push(t),s.contains.push(c) +;let g=[n,a];return[i,s,c,t].forEach((e=>{e.contains=e.contains.concat(g) +})),g=g.concat(i,s),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ +className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:g},{ +begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", +contains:g}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", +end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:g, +end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ +begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ +begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", +contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ +begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ +className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ +className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}})() +;hljs.registerLanguage("markdown",e)})();/*! `plaintext` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var t=(()=>{"use strict";return t=>({name:"Plain text", +aliases:["text","txt"],disableAutodetect:!0})})() +;hljs.registerLanguage("plaintext",t)})();/*! `xml` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const a=e.regex,n=a.concat(/[\p{L}_]/u,a.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),s={ +className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},t={begin:/\s/, +contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] +},i=e.inherit(t,{begin:/\(/,end:/\)/}),c=e.inherit(e.APOS_STRING_MODE,{ +className:"string"}),l=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),r={ +endsWithParent:!0,illegal:/`]+/}]}]}]};return{ +name:"HTML, XML", +aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], +case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[t,l,c,i,{begin:/\[/,end:/\]/,contains:[{ +className:"meta",begin://,contains:[t,i,l,c]}]}] +},e.COMMENT(//,{relevance:10}),{begin://, +relevance:10},s,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, +relevance:10,contains:[l]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"style"},contains:[r],starts:{ +end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"script"},contains:[r],starts:{ +end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ +className:"tag",begin:/<>|<\/>/},{className:"tag", +begin:a.concat(//,/>/,/\s/)))), +end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:r}]},{ +className:"tag",begin:a.concat(/<\//,a.lookahead(a.concat(n,/>/))),contains:[{ +className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}} +})();hljs.registerLanguage("xml",e)})();/*! `yaml` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n="true false yes no null",a="[\\w#;/?:@&=+$,.~*'()[\\]]+",s={ +className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ +},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", +variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(s,{ +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={ +end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},t={begin:/\{/, +end:/\}/,contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]", +contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{ +begin:/\w[\w :()\./-]*:(?=[ \t]|$)/},{begin:/"\w[\w :()\./-]*":(?=[ \t]|$)/},{ +begin:/'\w[\w :()\./-]*':(?=[ \t]|$)/}]},{className:"meta",begin:"^---\\s*$", +relevance:10},{className:"string", +begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ +begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, +relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type", +begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a +},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", +begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", +relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ +className:"number", +begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" +},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},t,g,s],r=[...b] +;return r.pop(),r.push(i),l.contains=r,{name:"YAML",case_insensitive:!0, +aliases:["yml"],contains:b}}})();hljs.registerLanguage("yaml",e)})(); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..6faf77e --- /dev/null +++ b/index.html @@ -0,0 +1,451 @@ + + + + LOG4CL-EXTRAS - Addons for Log4CL + + + + + + + + + + + + +
Fork me on GitHub + + +

LOG4CL-EXTRAS - Addons for Log4CL

LOG4CL-EXTRAS ASDF System Details

Installation

You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:

(ql-dist:install-dist "http://dist.ultralisp.org/"
+                      :prompt nil)
+(ql:quickload :log4cl-extras)

Configuration

By default LOG4CL outputs log items like this:

CL-USER> (log:info "Hello")
+ <INFO> [01:15:37] cl-user () - Hello

However logging extra context fields requires a custom "layout". +Layout defines the way how the message will be formatted.

This system defines two layout types:

  • :PLAIN - a layout for printing messages to the REPL.

  • :JSON - a layout which outputs each message and all it's data + as a JSON documents. Use it to feed logs to Elastic Search + or a service like Datadog + to Papertrail.

To use these custom layouts, you have to use setup function. It also allows to set a log level +for root logger and appenders. Here is a minimal example showing how to configure logger for the REPL:

CL-USER> (log4cl-extras/config:setup
+          '(:level :debug
+            :appenders ((this-console :layout :plain))))
+NIL
+
+CL-USER> (log:info "Hello")
+<INFO> [2021-05-16T01:16:46.978992+03:00] Hello
+
+CL-USER> (log4cl-extras/context:with-fields (:foo "Bar")
+           (log:info "Hello"))
+<INFO> [2021-05-16T01:26:30.331849+03:00] Hello
+  Fields:
+    foo: Bar

If you replace :PLAIN with :JSON, you'll get this:

CL-USER> (log4cl-extras/config:setup
+          '(:level :debug
+            :appenders ((this-console :layout :json))))
+; No values
+CL-USER> (log4cl-extras/context:with-fields (:foo "Bar")
+           (log:info "Hello"))
+{"fields":{"foo":"Bar"},"level":"INFO","message":"Hello","timestamp":"2021-05-16T01:27:54.879336+03:00"}

Appender in terms of log4cl is a target for log output. You can combine multiple appenders +in a single call to setup function.

Here is the example of the config, suitable for production. Here we log all messages as JSON records +into the file, rotated on the daily basis. And all errors and warnings will be written to the REPL.

(log4cl-extras/config:setup
+ '(:level :debug
+   :appenders ((this-console :layout :plain
+                             :filter :warn)
+               (daily :layout :json
+                      :name-format "/app/logs/app.log"
+                      :backup-name-format "app-%Y%m%d.log"))))

Also, setup allows to change log levels for different loggers:

Setup loggers and appenders via confg.

Example:

(setup
+ '(:level :error
+   :appenders
+   (this-console
+    (file
+     :file "foo.log"
+     :layout json))
+   :loggers
+   ((log4cl-extras/config
+     :loggers
+     ((foo :level :debug)
+      (bar
+       :loggers
+       ((some-class
+         :level debug))))))))

As you can see, setup function accepts a plist with keys :LEVEL, :APPENDERS and :LOGGERS.

:LEVEL key holds a logging level for the root logger. It could be :INFO, :WARN or :ERROR.

:APPENDERS is a list of list where each sublist should start from the appender type and arguments for it's constructor.

Supported appenders are:

  • THIS-CONSOLE corresponds to LOG4CL:THIS-CONSOLE-APPENDER class.

  • DAILY corresponds to LOG4CL:DAILY-FILE-APPENDER class.

  • FILE corresponds to LOG4CL:FILE-APPENDER.

To lookup supported arguments for each appender type, see these classes initargs. +the only difference is that :LAYOUT argument is processed in a special way: +:JSON value replaced with log4cl-extras/json:json-layout and :PLAIN is replaced +with log4cl-extras/plain:plain-layout.

And finally, you can pass to setup a list of loggers. Each item in this list +should be plist where first item is a symbolic name of a package or a function name +inside a package and other items are params for a nested setup call.

Layouts

Context Fields

Macro with-fields let to to capture some information into the dynamic variable. +All messages logged inside the with-fields form will have these fields attached:

CL-USER> (log4cl-extras/config:setup
+          '(:level :debug
+            :appenders ((this-console :layout :plain))))
+
+CL-USER> (defun process-request ()
+           (log:info "Processing request"))
+
+CL-USER> (log4cl-extras/context:with-fields (:request-id 42)
+           (process-request))
+<INFO> [2020-07-19T10:03:21.079636Z] Processing request
+  Fields:
+    request-id: 42
+
+;; Now let's switch to JSON layout:
+CL-USER> (log4cl-extras/config:setup
+          '(:level :debug
+            :appenders ((this-console :layout :json))))
+
+CL-USER> (log4cl-extras/context:with-fields (:request-id 42)
+           (process-request))
+{"fields": {"request-id": 42},
+ "level": "INFO",
+ "message": "Processing request",
+ "timestamp": "2020-07-19T10:03:32.855593Z"}

Beware!, catching context fields costs some time even if they are not logged.

Captures content of given fields into a dynamic variable.

These fields will be logged along with any log entry +inside the with-fields body.

Returns an alist of all fields defined using with-fields macro in the current stack.

Keys are returned as downcased strings, prepared for logging.

Logging Unhandled Errors

Quickstart

If you want to log unhandled signals traceback, then use with-log-unhandled macro.

Usually it is good idea, to use with-log-unhandled in the main function or in a function which handles +a HTTP request.

If some error condition will be signaled by the body, it will be logged as an error with "traceback" +field like this:

CL-USER> (defun foo ()
+           (error "Some error happened"))
+
+CL-USER> (defun bar ()
+           (foo))
+
+CL-USER> (log4cl-extras/error:with-log-unhandled ()
+           (bar))
+
+<ERROR> [2020-07-19T10:14:39.644805Z] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+    File "NIL", line NIL, in FOO
+      (FOO)
+    File "NIL", line NIL, in BAR
+      (BAR)
+    File "NIL", line NIL, in (LAMBDA (…
+      ((LAMBDA ()))
+    File "NIL", line NIL, in SIMPLE-EV…
+      (SB-INT:SIMPLE-EVAL-IN-LEXENV
+       (LOG4CL-EXTRAS/ERROR:WITH-LOG-UNHANDLED NIL
+         (BAR))
+       #<NULL-LEXENV>)
+    ...
+       #<CLOSURE (LAMBDA () :IN SLYNK::CALL-WITH-LISTENER) {100A6B043B}>)
+     
+     
+  Condition: Some error happened
+; Debugger entered on #<SIMPLE-ERROR "Some error happened" {100A7A5DB3}>

The JSON layout will write such error like this:

{
+  "fields": {
+    "traceback": "Traceback (most recent call last):\n  File \"NIL\", line NIL, in FOO\n    (FOO)\n  File \"NIL\", line NIL, in BAR\n    (BAR)\n...\nCondition: Some error happened"
+  },
+  "level": "ERROR",
+  "message": "Unhandled exception",
+  "timestamp": "2020-07-19T10:21:33.557418Z"
+}

Printing Backtrace

There is a helper function print-backtrace for extracting and printing backtrace, which can be used +separately from logging. One use case is to render backtrace on the web page when a +site is in a debug mode:

CL-USER> (log4cl-extras/error:print-backtrace :depth 3)
+Traceback (most recent call last):
+   0 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/eval.lisp", line 291
+       In SB-INT:SIMPLE-EVAL-IN-LEXENV
+     Args ((LOG4CL-EXTRAS/ERROR:PRINT-BACKTRACE :DEPTH 3) #<NULL-LEXENV>)
+   1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/eval.lisp", line 311
+       In EVAL
+     Args ((LOG4CL-EXTRAS/ERROR:PRINT-BACKTRACE :DEPTH 3))
+   2 File "/Users/art/projects/lisp/sly/contrib/slynk-mrepl.lisp"
+       In (LAMBDA () :IN SLYNK-MREPL::MREPL-EVAL-1)
+     Args ()

By default, it prints to the *DEBUG-IO*, but you can pass it a :STREAM argument +which has the same semantic as a stream for FORMAT function.

Other useful parameters are :DEPTH and :MAX-CALL-LENGTH. They allow to control how +long and wide backtrace will be.

Also, you might pass :CONDITION. If it is given, it will be printed after the backtrace.

And finally, you can pass a list of functions to filter arguments before printing. +This way secret or unnecesary long values can be stripped. See the next section to learn +how to not log secret values.

API

Keeps default value for traceback depth logged by with-log-unhandled macro

The max length of each line in a traceback. It is useful to limit it because otherwise some log collectors can discard the whole log entry.

Add to this variable functions of two arguments to change arguments before they will be dumped +as part of the backtrace to the log.

This is not a special variable, because it should be changed system-wide and can be accessedd +from multiple threads.

Add to this variable functions of zero arguments. Each function should return an argument filter +function suitable for using in the *args-filters* variable.

These constructors can be used to create argument filters with state suitable for +processing of a single backtrace only. For example, +log4cl-extras/secrets:make-secrets-replacer function, keeps tracks every secret value used in +all frames of the backtrace. We don't want to keep these values forever and to mix secrets +of different users in the same place. Thus this function should be used as a "constructor". +In this case it will create a new secret replacer for every backtrace to be processed.

macro
(&key (depth \*max-traceback-depth\*) (errors-to-ignore nil)) &body body

Logs any ERROR condition signaled from the body. Logged message will have a "traceback" field.

You may specify a list of error classes to ignore as ERRORS-TO-IGNORE argument. +Errors matching (typep err ) will not be logged as "Unhandled".

function
&key (stream \*debug-io\*) (condition nil) (depth \*max-traceback-depth\*) (max-call-length \*max-call-length\*) (args-filters (get-current-args-filters)) (format-condition #'format-condition-object)

A helper to print backtrace. Could be useful to out backtrace +at places other than logs, for example at a web page.

This function applies the same filtering rules as with-log-unhandled macro.

By default condition description is printed like this:

Condition REBLOCKS-WEBSOCKET:NO-ACTIVE-WEBSOCKETS: No active websockets bound to the current page.

But you can change this by providing an argument FORMAT-CONDITION. It should be a +function of two arguments: (stream condition).

Returns a function, suitable to be used in *args-filters* variable.

Function PREDICATE will be applied to each argument in the frame +and if it returns T, then argument will be replaced with PLACEHOLDER.

Objects of this class can be used as replacement to arguments in a backtrace.

They are printed like #<some-name>.

This form was choosen to match the way how SBCL shows unused arguments: #<unused argument>.

Placeholders should be created with make-placeholder function.

Creates a placeholder for some secret value or omitted argument.

CL-USER> (log4cl-extras/error:make-placeholder "secret value")
+
+#<secret value>

See Hard Way section to learn, how to use +placeholders to remove sensitive information from logs.

How Keep Secrets Out of Logs

When backtrace is printed to log files it is good idea to omit passwords, tokens, cookies, +and other potentially sensitive values.

Here is a potential situation where you have a password and trying to create a new connection +to the database. But because of some network error, an unhandled error along with a backtrace +will be logged. Pay attention to our secret password in the log:

CL-USER> (log4cl-extras/config:setup
+           '(:level :error
+             :appenders ((this-console :layout plain))))
+   
+CL-USER> (defun connect (password)
+           "Normally, we don't control this function's code
+  because it is from the third-party library."
+           (check-type password string)
+           (error "Network timeout"))
+   
+CL-USER> (defun authenticate (password)
+           "This function is in our app's codebase.
+  It is calling a third-party DB driver."     
+           (connect password))
+   
+CL-USER> (defun bar (password)
+           (authenticate password))
+   
+CL-USER> (log4cl-extras/error:with-log-unhandled (:depth 5)
+           (bar "The Secret Password"))
+<ERROR> [2021-01-24T14:13:24.460890+03:00] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+     0 File "unknown"
+         In (FLET "H0")
+       Args (#<SIMPLE-ERROR "Network timeout" {100F065533}>)
+     1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 81
+         In SB-KERNEL::%SIGNAL
+       Args (#<SIMPLE-ERROR "Network timeout" {100F065533}>)
+     2 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 154
+         In ERROR
+       Args ("Network timeout")
+     3 File "unknown"
+         In CONNECT
+       Args ("The Secret Password")
+     4 File "unknown"
+         In AUTHENTICATE
+       Args ("The Secret Password")
+  
+  Condition: Network timeout

With log4cl-extras you can keep values in secret in two ways.

Easy Way

The easiest way, is to wrap all sensitive data using +secret-values +library as soon as possible and unwrap them only before usage.

Lets see what will happen if we'll use a wrapped password.

First, we need to teach AUTHENTICATE function, how to unwrap +the password, before passing it to the driver:

CL-USER> (defun authenticate (password)
+           "This function is in our app's codebase.
+  It is calling a third-party DB driver."
+           (connect
+            (secret-values:ensure-value-revealed
+             password)))

Next, we need to wrap password into a special object. It is better to +do this as soon as possible. In production code you'll probably have +something like (secret-values:conceal-value (uiop:getenv "POSTGRES_PASSWORD")):

CL-USER> (log4cl-extras/error:with-log-unhandled (:depth 5)
+           (bar (secret-values:conceal-value
+                 "The Secret Password")))
+<ERROR> [2021-01-24T14:16:01.667651+03:00] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+     0 File "unknown"
+         In (FLET "H0")
+       Args (#<SIMPLE-ERROR "Network timeout" {10036CB1A3}>)
+     1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 81
+         In SB-KERNEL::%SIGNAL
+       Args (#<SIMPLE-ERROR "Network timeout" {10036CB1A3}>)
+     2 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 154
+         In ERROR
+       Args ("Network timeout")
+     3 File "unknown"
+         In CONNECT
+       Args ("The Secret Password")
+     4 File "unknown"
+         In AUTHENTICATE
+       Args (#<SECRET-VALUES:SECRET-VALUE {10036CB183}>)
+     
+  Condition: Network timeout

Pay attention to the fourth stack frame. AUTHENTICATE function has +#<SECRET-VALUES:SECRET-VALUE {10036CB183}> as the first argument. +But why do we see "The Secret Password" in the third frame anyway?

It is because we have to pass a raw version of the password to the libraries +we don't control.

Here is where log4cl-extras comes to the resque. It provides a package +LOG4CL-EXTRAS/SECRETS. It is optional and is not loaded together with the +primary system.

Earlier, I've mentioned :ARGS-FILTERS argument to the log4cl-extras/error:print-backtrace function. +Package LOG4CL-EXTRAS/SECRETS provides a function make-secrets-replacer +which can be used to filter secret values.

We can add it into the global variable log4cl-extras/error:*args-filter-constructors* like this:

CL-USER> (ql:quickload :log4cl-extras/secrets)
+(:LOG4CL-EXTRAS/SECRETS)
+   
+CL-USER> (setf log4cl-extras/error:*args-filter-constructors*
+               (list 'log4cl-extras/secrets:make-secrets-replacer))
+(#<FUNCTION LOG4CL-EXTRAS/SECRETS:MAKE-SECRETS-REPLACER>)

Now let's try to connect to our fake database again:

CL-USER> (log4cl-extras/error:with-log-unhandled (:depth 5)
+           (bar (secret-values:conceal-value
+                 "The Secret Password")))
+<ERROR> [2021-01-24T14:27:17.851716+03:00] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+     0 File "unknown"
+         In (FLET "H0")
+       Args (#<SIMPLE-ERROR "Network timeout" {100800F723}>)
+     1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 81
+         In SB-KERNEL::%SIGNAL
+       Args (#<SIMPLE-ERROR "Network timeout" {100800F723}>)
+     2 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 154
+         In ERROR
+       Args ("Network timeout")
+     3 File "unknown"
+         In CONNECT
+       Args (#<secret value>)
+     4 File "unknown"
+         In AUTHENTICATE
+       Args (#<secret value>)
+  
+  Condition: Network timeout

Now both third and fourth frames show #<secret value> instead of the password. +This is because (log4cl-extras/secrets:make-secrets-replacer) call returns a closure +which remembers and replaces raw values of the secrets too!

Hard Way

Sometimes it is desireable to remove from tracebacks other kinds of data. +For example I don't want to see Lack's +environments, because of a few reasons:

  • they contain cookies and it is insecure to log them;

  • they may contain HTTP header with tokens;

  • env objects are list with large amount of data and this makes tracebacks unreadable.

Let's create a filter for arguments, which will replace Lack's environments +with a placeholder.

First, we need to create a placeholder object:

CL-USER> (defvar +lack-env-placeholder+
+           (log4cl-extras/error:make-placeholder "lack env"))
++LACK-ENV-PLACEHOLDER+

Next, we need to define a filter function. Each filter function should accept +two arguments:

  • a function's name, which can be a symbol or a list like (:method foo-bar (...))

  • a list of arguments.

Filter should return two values, which can be the same is inputs or a transformed in some way.

For example, we know that the Lack's env is a plist with :REQUEST-METHOD, :REQUEST-URI and other values. +We can to write a predicate like this:

CL-USER> (defun lack-env-p (arg)
+           (and (listp arg)
+                (member :request-method arg)
+                (member :request-uri arg)))

And to use it in our filter:

CL-USER> (defun remove-lack-env-from-frame (func-name args)
+           "Removes Lack's env from stackframes to make backtrace concise."
+           (values func-name
+                   (loop for arg in args
+                         if (lack-env-p arg)
+                           collect +lack-env-placeholder+
+                         else
+                           collect arg)))

Now let's try to use it:

CL-USER> (defun request-handler (app env)
+           (authenticate (secret-values:conceal-value
+                          "Secret password"))
+           (pass-further app env))
+   
+CL-USER> (setf log4cl-extras/error:*args-filters*
+               (list 'remove-lack-env-from-frame)
+               log4cl-extras/error:*args-filter-constructors*
+               ;; We need this too to keep DB password safe, remember?
+               (list 'log4cl-extras/secrets:make-secrets-replacer))

Now pay attention to the fifth frame, where second argument is replaced +with #<lack env>!!!

CL-USER> (log4cl-extras/error:with-log-unhandled (:depth 7)
+           (request-handler 42
+                            (list :request-method :post
+                                  :request-uri "/login/"
+                                  :cookies "Session hash, and other secrets.")))
+<ERROR> [2021-01-24T14:56:45.502656+03:00] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+     0 File "unknown"
+         In (FLET "H0")
+       Args (#<SIMPLE-ERROR "Network timeout" {1004233EB3}>)
+     1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 81
+         In SB-KERNEL::%SIGNAL
+       Args (#<SIMPLE-ERROR "Network timeout" {1004233EB3}>)
+     2 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 154
+         In ERROR
+       Args ("Network timeout")
+     3 File "unknown"
+         In CONNECT
+       Args (#<secret value>)
+     4 File "unknown"
+         In AUTHENTICATE
+       Args (#<secret value>)
+     5 File "unknown"
+         In REQUEST-HANDLER
+       Args (42 #<lack env>)
+     6 File "unknown"
+         In (LAMBDA ())
+       Args ()
+     
+  Condition: Network timeout

For such simple case like replacing args matching a predicate, log4cl-extras has a small helper log4cl-extras/error:make-args-filter:

CL-USER> (setf log4cl-extras/error:*args-filters*
+               (list (log4cl-extras/error:make-args-filter
+                      'lack-env-p
+                      (log4cl-extras/error:make-placeholder "LACK ENV BEING HERE")))
+               log4cl-extras/error:*args-filter-constructors*
+               ;; We need this too to keep DB password safe, remember?
+               (list 'log4cl-extras/secrets:make-secrets-replacer))
+   
+<ERROR> [2021-01-24T15:09:48.839513+03:00] Unhandled exception
+  Fields:
+  Traceback (most recent call last):
+     0 File "unknown"
+         In (FLET "H0")
+       Args (#<SIMPLE-ERROR "Network timeout" {1003112243}>)
+     1 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 81
+         In SB-KERNEL::%SIGNAL
+       Args (#<SIMPLE-ERROR "Network timeout" {1003112243}>)
+     2 File "/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp", line 154
+         In ERROR
+       Args ("Network timeout")
+     3 File "unknown"
+         In CONNECT
+       Args (#<secret value>)
+     4 File "unknown"
+         In AUTHENTICATE
+       Args (#<secret value>)
+     5 File "unknown"
+         In REQUEST-HANDLER
+       Args (42 #<LACK ENV BEING HERE>)
+     6 File "unknown"
+         In (LAMBDA ())
+       Args ()
+  
+  Condition: Network timeout

Returns a function which can be used to filter backtrace arguments.

Beware, don't add result of the call to make-secrets-replacer to +the log4cl-extras/error:*args-filters* variable, because it will +collect all secrets and keep them in memory until the end of the program.

Use log4cl-extras/error:*args-filter-constructors* instead, to keep +secrets only during the backtrace processing.

Appenders

In case of errors, LOG4CL removes appender from the logger. After that log message will be lost.

I don't like this behaviour and prefer to see such errors in logs and to log other +messages. This library defines a special appender classes which are not removed on errors but +output this message instead: "Caught SOME-ERROR: Error description - Unable to log the message.".

When you use log4cl-extras/config:setup function it automatically uses these appenders.

To debug logging errors interactively, you can set *debug-on-error* variable to T.

When T, then INVOKE-DEBUGGER will be called in case of any error during logging the message.

+
+
+ + \ No newline at end of file diff --git a/jquery.js b/jquery.js new file mode 100644 index 0000000..b061403 --- /dev/null +++ b/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 00 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + + +var splitChars = (function() { + var result = {}; + var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, + 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, + 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, + 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, + 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, + 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, + 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, + 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, + 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, + 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; + var i, j, start, end; + for (i = 0; i < singles.length; i++) { + result[singles[i]] = true; + } + var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], + [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], + [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], + [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], + [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], + [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], + [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], + [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], + [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], + [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], + [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], + [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], + [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], + [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], + [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], + [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], + [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], + [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], + [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], + [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], + [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], + [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], + [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], + [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], + [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], + [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], + [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], + [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], + [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], + [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], + [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], + [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], + [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], + [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], + [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], + [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], + [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], + [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], + [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], + [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], + [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], + [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], + [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], + [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], + [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], + [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], + [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], + [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], + [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; + for (i = 0; i < ranges.length; i++) { + start = ranges[i][0]; + end = ranges[i][1]; + for (j = start; j <= end; j++) { + result[j] = true; + } + } + return result; +})(); + +function splitQuery(query) { + var result = []; + var start = -1; + for (var i = 0; i < query.length; i++) { + if (splitChars[query.charCodeAt(i)]) { + if (start !== -1) { + result.push(query.slice(start, i)); + start = -1; + } + } else if (start === -1) { + start = i; + } + } + if (start !== -1) { + result.push(query.slice(start)); + } + return result; +} + + diff --git a/references.json b/references.json new file mode 100644 index 0000000..03c18fa --- /dev/null +++ b/references.json @@ -0,0 +1 @@ +[{"URL":"https://40ants.com/log4cl-extras/README.md#x-28LOG4CL-EXTRAS-2FDOC-3A-40README-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/DOC:@README","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E1-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.1.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E2-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.2.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E2-2E1-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.2.1|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E2-2E2-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.2.2|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E3-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.3.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E4-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.4.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E4-2E1-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.4.1|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E4-2E2-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.4.2|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E5-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.5.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E5-2E1-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.5.1|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E6-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.6.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E7-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.7.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E7-2E1-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.7.1|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E7-2E2-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.7.2|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E8-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.8.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E9-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.9.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E10-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.10.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-3A-7C0-2E11-2E0-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG::|0.11.0|","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/changelog/#x-28LOG4CL-EXTRAS-2FCHANGELOG-3A-40CHANGELOG-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CHANGELOG:@CHANGELOG","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3A-2ADEBUG-ON-ERROR-2A-20-28VARIABLE-29-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS:*DEBUG-ON-ERROR*","LOCATIVE":["VARIABLE"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3ADONT-DISABLE-MIXIN-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS:DONT-DISABLE-MIXIN","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-THIS-CONSOLE-APPENDER-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS:STABLE-THIS-CONSOLE-APPENDER","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-FILE-APPENDER-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS:STABLE-FILE-APPENDER","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-DAILY-FILE-APPENDER-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS:STABLE-DAILY-FILE-APPENDER","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FAPPENDERS-3A-3A-40APPENDERS-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/APPENDERS::@APPENDERS","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/SECRETS:MAKE-SECRETS-REPLACER","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3A-3A-40HARD-WAY-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/SECRETS::@HARD-WAY","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3A-3A-40EASY-WAY-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/SECRETS::@EASY-WAY","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FSECRETS-3A-3A-40KEEPING-SECRETS-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/SECRETS::@KEEPING-SECRETS","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-NAME-20-2840ANTS-DOC-2FLOCATIVES-3AREADER-20LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:PLACEHOLDER-NAME","LOCATIVE":["READER","PLACEHOLDER"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-P-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR:PLACEHOLDER-P","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AMAKE-PLACEHOLDER-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR:MAKE-PLACEHOLDER","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/ERROR:PLACEHOLDER","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AMAKE-ARGS-FILTER-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR:MAKE-ARGS-FILTER","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR:PRINT-BACKTRACE","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:WITH-LOG-UNHANDLED","LOCATIVE":["MACRO"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:*ARGS-FILTER-CONSTRUCTORS*","LOCATIVE":["VARIABLE"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTERS-2A-20-28VARIABLE-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:*ARGS-FILTERS*","LOCATIVE":["VARIABLE"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:*MAX-CALL-LENGTH*","LOCATIVE":["VARIABLE"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29","OBJECT":"LOG4CL-EXTRAS/ERROR:*MAX-TRACEBACK-DEPTH*","LOCATIVE":["VARIABLE"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-3A-40PRINTING-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR::@PRINTING","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-3A-40INTRO-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR::@INTRO","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FERROR-3A-3A-40ERRORS-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/ERROR::@ERRORS","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONTEXT-3AGET-FIELDS-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/CONTEXT:GET-FIELDS","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONTEXT-3AWITH-FIELDS-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29","OBJECT":"LOG4CL-EXTRAS/CONTEXT:WITH-FIELDS","LOCATIVE":["MACRO"]},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONTEXT-3A-3A-40CONTEXT-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CONTEXT::@CONTEXT","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FJSON-3AJSON-LAYOUT-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/JSON:JSON-LAYOUT","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FPLAIN-3APLAIN-LAYOUT-20CLASS-29","OBJECT":"LOG4CL-EXTRAS/PLAIN:PLAIN-LAYOUT","LOCATIVE":"CLASS"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONFIG-3ASETUP-20FUNCTION-29","OBJECT":"LOG4CL-EXTRAS/CONFIG:SETUP","LOCATIVE":"FUNCTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FCONFIG-3A-3A-40CONFIGURATION-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/CONFIG::@CONFIGURATION","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FDOC-3A-3A-40INSTALLATION-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/DOC::@INSTALLATION","LOCATIVE":"SECTION"},{"URL":"https://40ants.com/log4cl-extras/#x-28-23A-28-2813-29-20BASE-CHAR-20-2E-20-22log4cl-extras-22-29-20ASDF-2FSYSTEM-3ASYSTEM-29","OBJECT":"log4cl-extras","LOCATIVE":"SYSTEM"},{"URL":"https://40ants.com/log4cl-extras/#x-28LOG4CL-EXTRAS-2FDOC-3A-40INDEX-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29","OBJECT":"LOG4CL-EXTRAS/DOC:@INDEX","LOCATIVE":"SECTION"}] \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 0000000..ed911d2 --- /dev/null +++ b/search/index.html @@ -0,0 +1,87 @@ + + + + Search Page + + + + + + + + + + + + +
Fork me on GitHub + + +
+ + + + + +
+
+
+ + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 0000000..5c135d4 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames":["../index","../changelog"],"filenames":["../","../changelog/"],"objects":{"LOG4CL-EXTRAS/CONFIG":{"SETUP":[0,6,2,"x-28LOG4CL-EXTRAS-2FCONFIG-3ASETUP-20FUNCTION-29"]},"LOG4CL-EXTRAS/PLAIN":{"PLAIN-LAYOUT":[0,3,2,"x-28LOG4CL-EXTRAS-2FPLAIN-3APLAIN-LAYOUT-20CLASS-29"]},"LOG4CL-EXTRAS/JSON":{"JSON-LAYOUT":[0,3,2,"x-28LOG4CL-EXTRAS-2FJSON-3AJSON-LAYOUT-20CLASS-29"]},"LOG4CL-EXTRAS/CONTEXT":{"WITH-FIELDS":[0,12,2,"x-28LOG4CL-EXTRAS-2FCONTEXT-3AWITH-FIELDS-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"],"GET-FIELDS":[0,6,2,"x-28LOG4CL-EXTRAS-2FCONTEXT-3AGET-FIELDS-20FUNCTION-29"]},"LOG4CL-EXTRAS/ERROR":{"*MAX-TRACEBACK-DEPTH*":[0,22,2,"x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-TRACEBACK-DEPTH-2A-20-28VARIABLE-29-29"],"*MAX-CALL-LENGTH*":[0,22,2,"x-28LOG4CL-EXTRAS-2FERROR-3A-2AMAX-CALL-LENGTH-2A-20-28VARIABLE-29-29"],"*ARGS-FILTERS*":[0,22,2,"x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTERS-2A-20-28VARIABLE-29-29"],"*ARGS-FILTER-CONSTRUCTORS*":[0,22,2,"x-28LOG4CL-EXTRAS-2FERROR-3A-2AARGS-FILTER-CONSTRUCTORS-2A-20-28VARIABLE-29-29"],"WITH-LOG-UNHANDLED":[0,12,2,"x-28LOG4CL-EXTRAS-2FERROR-3AWITH-LOG-UNHANDLED-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29"],"PRINT-BACKTRACE":[0,6,2,"x-28LOG4CL-EXTRAS-2FERROR-3APRINT-BACKTRACE-20FUNCTION-29"],"MAKE-ARGS-FILTER":[0,6,2,"x-28LOG4CL-EXTRAS-2FERROR-3AMAKE-ARGS-FILTER-20FUNCTION-29"],"PLACEHOLDER":[0,3,2,"x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-20CLASS-29"],"MAKE-PLACEHOLDER":[0,6,2,"x-28LOG4CL-EXTRAS-2FERROR-3AMAKE-PLACEHOLDER-20FUNCTION-29"],"PLACEHOLDER-P":[0,6,2,"x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-P-20FUNCTION-29"],"PLACEHOLDER-NAME":[0,18,2,"x-28LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-NAME-20-2840ANTS-DOC-2FLOCATIVES-3AREADER-20LOG4CL-EXTRAS-2FERROR-3APLACEHOLDER-29-29"]},"LOG4CL-EXTRAS/SECRETS":{"MAKE-SECRETS-REPLACER":[0,6,2,"x-28LOG4CL-EXTRAS-2FSECRETS-3AMAKE-SECRETS-REPLACER-20FUNCTION-29"]},"LOG4CL-EXTRAS/APPENDERS":{"STABLE-DAILY-FILE-APPENDER":[0,3,2,"x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-DAILY-FILE-APPENDER-20CLASS-29"],"STABLE-FILE-APPENDER":[0,3,2,"x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-FILE-APPENDER-20CLASS-29"],"STABLE-THIS-CONSOLE-APPENDER":[0,3,2,"x-28LOG4CL-EXTRAS-2FAPPENDERS-3ASTABLE-THIS-CONSOLE-APPENDER-20CLASS-29"],"DONT-DISABLE-MIXIN":[0,3,2,"x-28LOG4CL-EXTRAS-2FAPPENDERS-3ADONT-DISABLE-MIXIN-20CLASS-29"],"*DEBUG-ON-ERROR*":[0,22,2,"x-28LOG4CL-EXTRAS-2FAPPENDERS-3A-2ADEBUG-ON-ERROR-2A-20-28VARIABLE-29-29"]}},"objnames":[["lisp","symbol","Symbol"],["lisp","argument","Argument"],["lisp","system","ASDF System"],["lisp","class","Class"],["lisp","compiler-macro","Compiler Macro"],["lisp","constant","Constant"],["lisp","function","Function"],["lisp","generic-function","Generic Function"],["lisp","glossary-term","Glossary Term"],["lisp","include","Included Block"],["lisp","stdout-of","Stdout of Code"],["lisp","locative","Locative"],["lisp","macro","Macro"],["lisp","method","Method"],["lisp","package","Package"],["lisp","restart","Restart"],["lisp","section","Section"],["lisp","accessor","Accessor"],["lisp","reader","Slot Reader"],["lisp","writer","Slot Write"],["lisp","structure-accessor","Structure Accessor"],["lisp","type","Type"],["lisp","variable","Variable"]],"objtypes":["lisp:symbol","lisp:argument","lisp:system","lisp:class","lisp:compiler-macro","lisp:constant","lisp:function","lisp:generic-function","lisp:glossary-term","lisp:include","lisp:stdout-of","lisp:locative","lisp:macro","lisp:method","lisp:package","lisp:restart","lisp:section","lisp:accessor","lisp:reader","lisp:writer","lisp:structure-accessor","lisp:type","lisp:variable"],"terms":{"Description:":[0],"A":[1,0],"bunch":[0],"of":[1,0],"addon":[0],"to":[1,0],"LOG4CL":[0],":":[0],"JSON":[0],"appender,":[0],"context":[0],"fields,":[0],"cross-fing":[0],"etc.":[0],"Licence:":[0],"BSD":[0],"Author:":[0],"Alexand":[0],"Artemenko":[0],"Homepage:":[0],"https://40ants.com/log4cl-extras/":[0],"Bug":[0],"tracker:":[0],"https://github.com/40ants/log4cl-extras/issu":[0],"Sourc":[0],"control:":[0],"GIT":[0],"Depend":[0],"on:":[0],"40ants-doc":[0],",":[1,0],"alexandria":[0],"cl-string":[0],"dissect":[0],"global-var":[0],"jonathan":[0],"local-tim":[0],"log4cl":[0],"named-readt":[0],"pythonic-string-read":[0],"with-output-to-stream":[0],"LOG4CL-EXTRAS":[0],"ASDF":[1,0],"System":[0],"Detail":[0],"You":[0],"can":[1,0],"instal":[0],"thi":[1,0],"librari":[1,0],"from":[1,0],"Quicklisp,":[0],"but":[1,0],"you":[1,0],"want":[0],"receiv":[0],"updat":[0],"quickly,":[0],"then":[0],"it":[1,0],"Ultralisp.org:":[0],"(ql-dist:install-dist":[0],"\"http://dist.ultralisp.org/\"\n":[0],":prompt":[0],"nil)\n(ql:quickload":[0],":log4cl-extras)":[0],"Installat":[0],"By":[1,0],"default":[1,0],"output":[1,0],"log":[1,0],"item":[0],"like":[1,0],"this:":[1,0],"CL-USER>":[0],"(log:info":[0],"\"Hello\")\n":[0],"":[0],"[01:15:37]":[0],"cl-user":[0],"()":[0],"-":[0],"Hello":[0],"Howev":[0],"extra":[0],"field":[1,0],"requir":[0],"a":[1,0],"custom":[0],"\"layout\".\nLayout":[0],"defin":[1,0],"the":[1,0],"wai":[1,0],"how":[1,0],"messag":[1,0],"will":[1,0],"be":[1,0],"formatted.":[0],"Thi":[1,0],"system":[0],"two":[0],"layout":[0],"types:":[0],":PLAIN":[1,0],"for":[1,0],"print":[1,0],"REPL":[1,0],".":[1,0],":JSON":[1,0],"which":[1,0],"each":[1,0],"and":[1,0],"all":[0],"it'":[0],"data\n":[0],"as":[1,0],"documents.":[0],"Use":[0],"feed":[0],"Elastic":[0],"Search\n":[0],"or":[1,0],"servic":[0],"Datadog":[0],"\n":[0],"Papertrail":[0],"To":[0],"us":[1,0],"these":[0],"layouts,":[0],"have":[0],"setup":[0],"function.":[0],"It":[1,0],"also":[0],"allow":[0],"set":[1,0],"level\nfor":[0],"root":[0],"logger":[1,0],"appenders.":[0],"Here":[0],"is":[1,0],"minim":[0],"exampl":[0],"show":[0],"configur":[0],"(log4cl-extras/config:setup\n":[0],"'(:level":[0],":debug\n":[0],":append":[0],"((this-consol":[0],":layout":[0],":plain))))\nNIL\n\nCL-USER>":[0],"\"Hello\")\n":[0],"[2021-05-16T01:16:46.978992+03:00]":[0],"Hello\n\nCL-USER>":[0],"(log4cl-extras/context:with-field":[0],"(:foo":[0],"\"Bar\")\n":[0],"\"Hello\"))\n":[0],"[2021-05-16T01:26:30.331849+03:00]":[0],"Hello\n":[0],"Fields:\n":[0],"foo:":[0],"Bar":[0],"If":[0],"replac":[1,0],"with":[1,0],"you'll":[0],"get":[0],":json))))\n;":[0],"No":[1,0],"values\nCL-USER>":[0],"\"Hello\"))\n{\"fields\":{\"foo\":\"Bar\"},\"level\":\"INFO\",\"message\":\"Hello\",\"timestamp\":\"2021-05-16T01:27:54.879336+03:00\"}":[0],"Appender":[0],"in":[1,0],"term":[0],"target":[0],"output.":[1,0],"combin":[0],"multipl":[0],"appenders\nin":[0],"singl":[0],"call":[1,0],"config,":[0],"suitabl":[0],"production.":[0],"we":[0],"records\ninto":[0],"file,":[0],"rotat":[0],"on":[1,0],"daili":[0],"basis.":[0],"And":[0],"error":[1,0],"warn":[1,0],"written":[0],":plain\n":[0],":filter":[0],":warn)\n":[0],"(daili":[0],":json\n":[0],":name-format":[0],"\"/app/logs/app.log\"\n":[0],":backup-name-format":[0],"\"app-%Y%m%d.log\"))))":[0],"Also,":[1,0],"chang":[1,0],"level":[0],"differ":[0],"loggers:":[0],"Setup":[0],"append":[1,0],"via":[0],"confg.":[0],"Example:":[0],"(setup\n":[0],":error\n":[0],":appenders\n":[0],"(this-console\n":[0],"(file\n":[0],":file":[0],"\"foo.log\"\n":[0],"json))\n":[0],":loggers\n":[0],"((log4cl-extras/config\n":[0],"((foo":[0],":level":[0],":debug)\n":[0],"(bar\n":[0],"((some-class\n":[0],"debug))))))))":[0],"As":[0],"see,":[0],"function":[1,0],"accept":[1,0],"plist":[0],"kei":[1,0],":LEVEL":[0],":APPENDERS":[0],":LOGGERS":[0],"hold":[0],"logger.":[0],"could":[0],":INFO":[0],":WARN":[0],":ERROR":[0],"list":[1,0],"where":[0],"sublist":[0],"should":[1,0],"start":[0],"type":[1,0],"argument":[1,0],"constructor.":[0],"Support":[0],"are:":[0],"THIS-CONSOLE":[0],"correspond":[0],"LOG4CL:THIS-CONSOLE-APPENDER":[0],"class.":[0],"DAILY":[0],"LOG4CL:DAILY-FILE-APPENDER":[0],"FILE":[0],"LOG4CL:FILE-APPENDER":[0],"lookup":[0],"support":[0],"type,":[0],"see":[0],"class":[0],"initargs.\nth":[0],"onli":[1,0],"that":[0],":LAYOUT":[0],"process":[1,0],"special":[1,0],"way:\n":[0],"valu":[1,0],"log4cl-extras/json:json-layout":[0],"replaced\nwith":[0],"log4cl-extras/plain:plain-layout":[0],"finally,":[0],"pass":[1,0],"loggers.":[0],"Each":[0],"list\nshould":[0],"first":[0],"symbol":[0],"name":[1,0],"packag":[0],"name\ninsid":[0],"other":[0],"ar":[1,0],"param":[0],"nest":[1,0],"call.":[0],"Layout":[0],"Configur":[0],"Macro":[1,0],"with-field":[0],"let":[0],"captur":[0],"some":[1,0],"inform":[0],"into":[1,0],"dynam":[0],"variable.\nAl":[0],"insid":[0],"form":[0],"attached:":[0],":plain))))\n\nCL-USER>":[0],"(defun":[0],"process-request":[0],"()\n":[1,0],"\"Process":[0],"request\"))\n\nCL-USER>":[0],"(:request-id":[0],"42)\n":[0],"(process-request))\n":[0],"[2020-07-19T10:03:21.079636Z]":[0],"Process":[0],"request\n":[0],"request-id:":[0],"42\n\n;;":[0],"Now":[1,0],"let'":[0],"switch":[0],"layout:\nCL-USER>":[0],":json))))\n\nCL-USER>":[0],"(process-request))\n{\"fields\":":[0],"{\"request-id\":":[0],"42},\n":[0],"\"level\":":[0],"\"INFO\",\n":[0],"\"message\":":[0],"request\",\n":[0],"\"timestamp\":":[0],"\"2020-07-19T10:03:32.855593Z\"}":[0],"Beware!":[0],"catch":[1,0],"cost":[0],"time":[0],"even":[1,0],"if":[1,0],"thei":[0],"not":[1,0],"logged.":[1,0],"Captur":[0],"content":[0],"given":[0],"variable.":[1,0],"These":[0],"along":[1,0],"ani":[0],"entry\ninsid":[0],"body.":[0],"Return":[0],"an":[0],"alist":[0],"macro":[1,0],"current":[1,0],"stack.":[0],"Kei":[0],"return":[0],"downcas":[0],"strings,":[0],"prepar":[0],"logging.":[0],"Context":[0],"Field":[0],"unhandl":[0],"signal":[1,0],"traceback,":[0],"with-log-unhandl":[1,0],"macro.":[0],"Usualli":[0],"good":[0],"idea,":[0],"main":[0],"handles\na":[0],"HTTP":[1,0],"request.":[0],"condit":[1,0],"by":[1,0],"body,":[0],"\"traceback\"\nfield":[0],"foo":[0],"(error":[0],"\"Some":[0],"happened\"))\n\nCL-USER>":[0],"bar":[0],"(foo))\n\nCL-USER>":[0],"(log4cl-extras/error:with-log-unhandl":[0],"(bar))\n\n":[0],"[2020-07-19T10:14:39.644805Z]":[0],"Unhandl":[0],"exception\n":[0],"Traceback":[0],"(most":[0],"recent":[0],"last):\n":[0],"File":[1,0],"\"NIL\",":[0],"line":[1,0],"NIL,":[0],"FOO\n":[0],"(FOO)\n":[0],"BAR\n":[0],"(BAR)\n":[0],"(LAMBDA":[0],"(…\n":[0],"((LAMBDA":[0],"()))\n":[0],"SIMPLE-EV…\n":[0],"(SB-INT:SIMPLE-EVAL-IN-LEXENV\n":[0],"(LOG4CL-EXTRAS/ERROR:WITH-LOG-UNHANDLED":[0],"NIL\n":[0],"(BAR))\n":[0],"#)\n":[0],"...\n":[0],"#)\n":[0],"Condition:":[1,0],"Some":[0],"happened\n;":[0],"Debugg":[0],"enter":[0],"#":[0],"The":[0],"write":[0],"such":[1,0],"{\n":[0],"\"fields\":":[0],"\"traceback\":":[0],"\"Traceback":[0],"last):\\n":[0],"\\\"NIL\\\",":[0],"FOO\\n":[0],"(FOO)\\n":[0],"BAR\\n":[0],"(BAR)\\n...\\nCondition:":[0],"happened\"\n":[0],"},\n":[0],"\"ERROR\",\n":[0],"\"Unhandl":[0],"exception\",\n":[0],"\"2020-07-19T10:21:33.557418Z\"\n}":[0],"Quickstart":[0],"There":[0],"helper":[0],"print-backtrac":[0],"extract":[0],"backtrace,":[0],"used\nsepar":[0],"One":[0],"case":[1,0],"render":[0],"backtrac":[1,0],"web":[0],"page":[0],"when":[1,0],"a\nsit":[0],"debug":[1,0],"mode:":[0],"(log4cl-extras/error:print-backtrac":[0],":depth":[0],"3)\nTraceback":[0],"0":[0],"\"/Users/art/.roswell/src/sbcl-2.0.11/src/code/eval.lisp\",":[0],"291\n":[0],"In":[1,0],"SB-INT:SIMPLE-EVAL-IN-LEXENV\n":[0],"Arg":[1,0],"((LOG4CL-EXTRAS/ERROR:PRINT-BACKTRACE":[0],":DEPTH":[0],"3)":[0],"1":[1,0],"311\n":[0],"EVAL\n":[0],"3))\n":[0],"2":[0],"\"/Users/art/projects/lisp/sly/contrib/slynk-mrepl.lisp\"\n":[0],"SLYNK-MREPL::MREPL-EVAL-1)\n":[0],"default,":[0],"*DEBUG-IO*":[0],":STREAM":[0],"argument\nwhich":[0],"ha":[1,0],"same":[0],"semant":[0],"stream":[0],"FORMAT":[0],"Other":[0],"paramet":[0],":MAX-CALL-LENGTH":[0],"Thei":[0],"control":[0],"how\nlong":[0],"wide":[0],"be.":[1,0],"might":[0],":CONDITION":[0],"given,":[0],"after":[0],"backtrace.":[1,0],"filter":[1,0],"befor":[0],"printing.\nThi":[0],"secret":[1,0],"unnecesari":[0],"long":[1,0],"stripped.":[0],"See":[0],"next":[0],"section":[0],"learn\nhow":[0],"values.":[0],"Print":[0],"Backtrac":[1,0],"API":[1,0],"Keep":[0],"traceback":[1,0],"depth":[0],"max":[0],"length":[1,0],"traceback.":[1,0],"limit":[0],"becaus":[1,0],"otherwis":[0],"collector":[0],"discard":[0],"whole":[0],"entry.":[0],"Add":[0],"variabl":[1,0],"dumped\na":[0],"part":[1,0],"log.":[0],"variable,":[0],"system-wid":[0],"accessedd\nfrom":[0],"threads.":[0],"zero":[0],"arguments.":[0],"filter\nfunct":[0],"*args-filters*":[0],"constructor":[0],"creat":[1,0],"state":[0],"for\nprocess":[0],"only.":[0],"For":[0],"example,\n":[0],"log4cl-extras/secrets:make-secrets-replac":[1,0],"function,":[0],"keep":[0],"track":[0],"everi":[1,0],"in\nal":[0],"frame":[0],"We":[0],"don't":[0],"forev":[0],"mix":[0],"secrets\nof":[0],"user":[0],"place.":[0],"Thu":[0],"\"constructor\".\nIn":[0],"new":[1,0],"processed.":[0],"Log":[0],"ERROR":[1,0],"\"traceback\"":[0],"field.":[0],"mai":[0],"specifi":[0],"ignor":[0],"ERRORS-TO-IGNORE":[1,0],"argument.\nError":[0],"match":[0],"(typep":[0],"err":[0],")":[0],"\"Unhandled\".":[0],"Could":[0],"out":[0],"backtrace\nat":[0],"place":[0],"than":[0],"logs,":[0],"at":[0],"page.":[1,0],"appli":[0],"rule":[0],"descript":[1,0],"Condit":[1,0],"REBLOCKS-WEBSOCKET:NO-ACTIVE-WEBSOCKETS:":[1,0],"activ":[1,0],"websocket":[1,0],"bound":[1,0],"But":[0],"provid":[0],"FORMAT-CONDITION":[0],"a\nfunct":[0],"arguments:":[0],"(stream":[0],"condition)":[0],"Function":[1,0],"PREDICATE":[0],"frame\nand":[0],"T,":[0],"PLACEHOLDER":[0],"Object":[0],"#":[0],"wa":[1,0],"choosen":[0],"SBCL":[0],"unus":[0],"#":[1,0],"Placehold":[0],"make-placehold":[0],"Creat":[0],"placehold":[0],"omit":[0],"argument.":[0],"(log4cl-extras/error:make-placehold":[0],"\"secret":[0],"value\")\n\n#":[0],"Hard":[0],"Wai":[0],"learn,":[0],"use\nplacehold":[0],"remov":[1,0],"sensit":[1,0],"logs.":[0],"Error":[0],"When":[0],"file":[0],"idea":[0],"passwords,":[0],"tokens,":[0],"cookies,\nand":[0],"potenti":[0],"situat":[0],"password":[0],"try":[0],"connection\nto":[0],"database.":[0],"network":[0],"error,":[1,0],"backtrace\nwil":[0],"Pai":[0],"attent":[0],"our":[0],"log:":[0],"plain))))\n":[0],"\nCL-USER>":[0],"connect":[0],"(password)\n":[0],"\"Normally,":[0],"function'":[0],"code\n":[0],"third-parti":[0],"library.\"\n":[0],"(check-typ":[0],"string)\n":[0],"\"Network":[0],"timeout\"))\n":[0],"authent":[0],"\"Thi":[0],"app'":[0],"codebase.\n":[0],"DB":[0],"driver.\"":[0],"(connect":[0],"password))\n":[0],"(authent":[0],"(:depth":[0],"5)\n":[0],"(bar":[0],"\"The":[0],"Secret":[0],"Password\"))\n":[0],"[2021-01-24T14:13:24.460890+03:00]":[0],"\"unknown\"\n":[0],"(FLET":[0],"\"H0\")\n":[0],"(#)\n":[0],"\"/Users/art/.roswell/src/sbcl-2.0.11/src/code/cold-error.lisp\",":[0],"81\n":[0],"SB-KERNEL::%SIGNAL\n":[0],"154\n":[0],"ERROR\n":[0],"(\"Network":[0],"timeout\")\n":[0],"3":[0],"CONNECT\n":[0],"(\"The":[0],"Password\")\n":[0],"4":[0],"AUTHENTICATE\n":[0],"Network":[0],"timeout":[0],"With":[0],"log4cl-extra":[1,0],"ways.":[0],"easiest":[0],"way,":[0],"wrap":[0],"data":[0],"using\n":[0],"secret-valu":[0],"\nlibrari":[0],"soon":[0],"possibl":[0],"unwrap":[0],"them":[0],"usage.":[0],"Let":[0],"what":[0],"happen":[1,0],"we'll":[0],"password.":[0],"First,":[0],"need":[0],"teach":[0],"AUTHENTICATE":[0],"unwrap\nth":[0],"password,":[0],"driver:":[0],"driver.\"\n":[0],"(connect\n":[0],"(secret-values:ensure-value-revealed\n":[0],"password)))":[0],"Next,":[0],"object.":[0],"better":[0],"to\ndo":[0],"possible.":[0],"product":[0],"code":[0],"probabl":[0],"have\nsometh":[0],"(secret-values:conceal-valu":[0],"(uiop:getenv":[0],"\"POSTGRES_PASSWORD\"))":[0],"(secret-values:conceal-value\n":[0],"Password\")))\n":[0],"[2021-01-24T14:16:01.667651+03:00]":[0],"{10036CB1A3}>)\n":[0],"(#)\n":[0],"fourth":[0],"stack":[0],"frame.":[0],"has\n":[0],"#":[0],"argument.\nBut":[0],"why":[0],"do":[0],"Password\"":[0],"third":[0],"anyway?":[0],"raw":[0],"version":[1,0],"libraries\nw":[0],"control.":[0],"come":[0],"resque.":[0],"package\n":[0],"LOG4CL-EXTRAS/SECRETS":[0],"option":[1,0],"load":[1,0],"togeth":[0],"the\nprimari":[0],"system.":[1,0],"Earlier,":[0],"I've":[0],"mention":[0],":ARGS-FILTERS":[0],"log4cl-extras/error:print-backtrac":[1,0],"function.\nPackag":[0],"make-secrets-replac":[0],"\nwhich":[0],"add":[0],"global":[0],"log4cl-extras/error:*args-filter-constructors*":[1,0],"(ql:quickload":[0],":log4cl-extras/secrets)\n(:LOG4CL-EXTRAS/SECRETS)\n":[0],"(setf":[1,0],"log4cl-extras/error:*args-filter-constructors*\n":[0],"(list":[0],"'log4cl-extras/secrets:make-secrets-replacer))\n(#)":[0],"fake":[0],"databas":[0],"again:":[0],"[2021-01-24T14:27:17.851716+03:00]":[0],"{100800F723}>)\n":[0],"(#)\n":[0],"both":[0],"#":[0],"!!!":[0],"7)\n":[0],"(request-handl":[0],"42\n":[0],":post\n":[0],"\"/login/\"\n":[0],":cooki":[0],"\"Session":[0],"hash,":[0],"secrets.\")))\n":[0],"[2021-01-24T14:56:45.502656+03:00]":[0],"{1004233EB3}>)\n":[0],"5":[0],"REQUEST-HANDLER\n":[0],"(42":[0],"env>)\n":[0],"6":[0],"())\n":[0],"simpl":[0],"predicate,":[0],"small":[0],"log4cl-extras/error:make-args-filt":[0],"(log4cl-extras/error:make-args-filter\n":[0],"'lack-env-p\n":[0],"\"LACK":[0],"ENV":[0],"BEING":[0],"HERE\")))\n":[0],"'log4cl-extras/secrets:make-secrets-replacer))\n":[0],"\n":[0],"[2021-01-24T15:09:48.839513+03:00]":[0],"{1003112243}>)\n":[0],"#)\n":[0],"Beware,":[0],"result":[0],"to\nth":[0],"log4cl-extras/error:*args-filters*":[1,0],"will\ncollect":[0],"memori":[0],"until":[0],"end":[1,0],"program.":[0],"instead,":[0],"keep\nsecret":[0],"dure":[1,0],"processing.":[0],"How":[0],"Out":[0],"errors,":[0],"After":[1,0],"lost.":[0],"behaviour":[0],"prefer":[0],"other\nmessages.":[0],"but\noutput":[0],"instead:":[0],"\"Caught":[0],"SOME-ERROR":[0],"Unabl":[0],"message.\".":[0],"log4cl-extras/config:setup":[1,0],"automat":[0],"interactively,":[0],"*debug-on-error*":[0],"T.":[0],"INVOKE-DEBUGGER":[0],"message.":[0],"Addon":[0],"Log4CL":[0],"log4cl-extras/error:with-log-unhandl":[1],"now":[1],"handl":[1],"SERIOUS-CONDITION":[1],"important,":[1],"subclass":[1],"SB-EXT:TIMEOUT":[1],"inherit":[1],"directli":[1],"old":[1],"abl":[1],"errors.":[1],"Chang":[1],"0.11.0":[1],"(2024-03-01)":[1],"Variabl":[1],"log4cl-extras/appenders:*debug-on-error*":[1],"ad":[1],"issu":[1],"messages.\nWhen":[1],"NIL":[1],"\"Unabl":[1],"message\"":[1],"errors\ndur":[1],"New":[1],"Packag":[1],"loaded.":[1],"fix":[1],"about":[1],"miss":[1],"package.":[1],"Fix":[1],"0.10.0":[1],"(2023-11-19)":[1],"like:":[1],"of:":[1],"0.9.0":[1],"(2022-12-30)":[1],"argument.\nY":[1],"class-nam":[1],"0.8.0":[1],"(2022-11-04)":[1],"printer":[1],"work":[1],"Clozur":[1],"CL":[1],"0.7.2":[1],"(2022-10-03)":[1],"mask":[1],"string":[1],"lists.\n":[1],"leak":[1],"Author":[1],"token":[1],"Previously,":[1],"\"/Users/art/projects/lisp/cloud-analyzer/.qlot/dists/ultralisp/software/fukamachi-dexador-20220619102143/src/backend/usocket.lisp\",":[1],"451\n":[1],"DEXADOR.BACKEND.USOCKET:REQUEST\n":[1],"(#\")))":[1],"introduced.":[1],"together\n":[1],"prevent":[1],"program":[1],"life.":[1],"Previosly,":[1],"store":[1],"variable,\nal":[1],"were":[1],"closure'":[1],"state.":[1],"When\n":[1],"used,":[1],"created\nfor":[1],"0.7.1":[1],"(2022-08-06)":[1],"intern":[1],"fly":[1],"log4cl-extras/error:*max-traceback-depth*":[1],"log4cl-extras/error:*max-call-length*":[1],"documented.":[1],"0.7.0":[1],"(2022-07-03)":[1],"logger'":[1],"category,":[1],"filenam":[1],"callabl":[1],"name.":[1],"0.6.0":[1],"(2021-10-03)":[1],"fail":[1],"some-func)":[1],"0.5.1":[1],"(2021-03-02)":[1],"TRACEBACK-TO-STRING":[1],"and\n":[1],"now\n":[1],"public":[1],"Added":[1],"abil":[1],"values.\n":[1],"Read":[1],"documentation,":[1],"lear":[1],"more.":[1],"0.5.0":[1],"(2021-01-24)":[1],"argument'":[1],"print-object":[1],"error.":[1],"Becaus":[1],"nasti":[1],"sometim":[1],"didn't":[1],"\"Unandl":[1],"error\".":[1],"DEPTH":[1],"10":[1],"default.":[1],"overriden":[1],"Also":[1],"anoth":[1],"control\n":[1],"method":[1],"100,":[1],"along\n":[1],"their":[1],"longer.":[1],"0.4.2":[1],"(2020-11-26)":[1],"depend":[1],"CL-STRINGS":[1],"0.4.1":[1],"(2019-03-05)":[1],"mode":[1],"human\nread":[1],"SLY":[1],"'s":[1],"All":[1],"are\nprint":[1],"well,":[1],"includ":[1],"Improve":[1],"0.4.0":[1],"(2019-03-04)":[1],"condition'":[1],"0.3.0":[1],"(2019-01-07)":[1],"system'":[1],"environ":[1],"C":[1],"locale.":[1],"close":[1],"report":[1],"pull":[1],"request":[1],"#1.":[1],"0.2.2":[1],"(2018-12-08)":[1],"signal,\n":[1],"deriv":[1],"that,\n":[1],"non":[1],"that:":[1],"lisp\n":[1],"(log4cl-json/error:with-log-unhandl":[1],"(signal":[1],"\"foo\"))\n":[1],"bad":[1],"behavior":[1],"0.2.1":[1],"(2018-11-24)":[1],"0.2.0":[1],"(2017-08-29)":[1],"Initial":[1],"version.":[1],"0.1.0":[1],"(2017-01-23)":[1],"ChangeLog":[1]},"titles":["LOG4CL-EXTRAS - Addons for Log4CL","ChangeLog"],"titleterms":[]}) diff --git a/searchtools.js b/searchtools.js new file mode 100644 index 0000000..c0180d7 --- /dev/null +++ b/searchtools.js @@ -0,0 +1,532 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +if (!Scorer) { + /** + * Simple result scoring code. + */ + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2 + }; +} + +if (!splitQuery) { + function splitQuery(query) { + return query.split(/\s+/); + } +} + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + htmlToText : function(htmlString) { + var virtualDocument = document.implementation.createHTMLDocument('virtual'); + var htmlElement = $(htmlString, virtualDocument); + htmlElement.find('.headerlink').remove(); + docContent = htmlElement.find('[role=main]')[0]; + if(docContent === undefined) { + console.warn("Content block not found. Sphinx search tries to obtain it " + + "via '[role=main]'. Could you check your theme or template."); + return ""; + } + return docContent.textContent || docContent.innerText; + }, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

 

').appendTo(this.out); + this.output = $('