| @ -1,2 +1,4 @@ | |||
| *.egg-info | |||
| *.py[co] | |||
| build | |||
| dist | |||
| @ -0,0 +1,4 @@ | |||
| # Sphinx build info version 1 | |||
| # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | |||
| config: 930d1a487dcd8b332a22e478cc0412db | |||
| tags: 645f666f9bcd5a90fca523b33c5a78b7 | |||
| @ -0,0 +1,12 @@ | |||
| .. importhook documentation master file, created by | |||
| sphinx-quickstart on Thu Aug 23 18:27:59 2018. | |||
| You can adapt this file completely to your liking, but it should at least | |||
| contain the root `toctree` directive. | |||
| .. toctree:: | |||
| :maxdepth: 2 | |||
| :caption: Contents: | |||
| .. automodule:: importhook | |||
| :members: | |||
| @ -0,0 +1,688 @@ | |||
| @import url("basic.css"); | |||
| /* -- page layout ----------------------------------------------------------- */ | |||
| body { | |||
| font-family: Georgia, serif; | |||
| font-size: 17px; | |||
| background-color: #fff; | |||
| color: #000; | |||
| margin: 0; | |||
| padding: 0; | |||
| } | |||
| div.document { | |||
| width: 940px; | |||
| margin: 30px auto 0 auto; | |||
| } | |||
| div.documentwrapper { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| div.bodywrapper { | |||
| margin: 0 0 0 220px; | |||
| } | |||
| div.sphinxsidebar { | |||
| width: 220px; | |||
| font-size: 14px; | |||
| line-height: 1.5; | |||
| } | |||
| hr { | |||
| border: 1px solid #B1B4B6; | |||
| } | |||
| div.body { | |||
| background-color: #fff; | |||
| color: #3E4349; | |||
| padding: 0 30px 0 30px; | |||
| } | |||
| div.body > .section { | |||
| text-align: left; | |||
| } | |||
| div.footer { | |||
| width: 940px; | |||
| margin: 20px auto 30px auto; | |||
| font-size: 14px; | |||
| color: #888; | |||
| text-align: right; | |||
| } | |||
| div.footer a { | |||
| color: #888; | |||
| } | |||
| p.caption { | |||
| font-family: inherit; | |||
| font-size: inherit; | |||
| } | |||
| div.relations { | |||
| display: none; | |||
| } | |||
| div.sphinxsidebar a { | |||
| color: #444; | |||
| text-decoration: none; | |||
| border-bottom: 1px dotted #999; | |||
| } | |||
| div.sphinxsidebar a:hover { | |||
| border-bottom: 1px solid #999; | |||
| } | |||
| div.sphinxsidebarwrapper { | |||
| padding: 18px 10px; | |||
| } | |||
| div.sphinxsidebarwrapper p.logo { | |||
| padding: 0; | |||
| margin: -10px 0 0 0px; | |||
| text-align: center; | |||
| } | |||
| div.sphinxsidebarwrapper h1.logo { | |||
| margin-top: -10px; | |||
| text-align: center; | |||
| margin-bottom: 5px; | |||
| text-align: left; | |||
| } | |||
| div.sphinxsidebarwrapper h1.logo-name { | |||
| margin-top: 0px; | |||
| } | |||
| div.sphinxsidebarwrapper p.blurb { | |||
| margin-top: 0; | |||
| font-style: normal; | |||
| } | |||
| div.sphinxsidebar h3, | |||
| div.sphinxsidebar h4 { | |||
| font-family: Georgia, serif; | |||
| color: #444; | |||
| font-size: 24px; | |||
| font-weight: normal; | |||
| margin: 0 0 5px 0; | |||
| padding: 0; | |||
| } | |||
| div.sphinxsidebar h4 { | |||
| font-size: 20px; | |||
| } | |||
| div.sphinxsidebar h3 a { | |||
| color: #444; | |||
| } | |||
| div.sphinxsidebar p.logo a, | |||
| div.sphinxsidebar h3 a, | |||
| div.sphinxsidebar p.logo a:hover, | |||
| div.sphinxsidebar h3 a:hover { | |||
| border: none; | |||
| } | |||
| div.sphinxsidebar p { | |||
| color: #555; | |||
| margin: 10px 0; | |||
| } | |||
| div.sphinxsidebar ul { | |||
| margin: 10px 0; | |||
| padding: 0; | |||
| color: #000; | |||
| } | |||
| div.sphinxsidebar ul li.toctree-l1 > a { | |||
| font-size: 120%; | |||
| } | |||
| div.sphinxsidebar ul li.toctree-l2 > a { | |||
| font-size: 110%; | |||
| } | |||
| div.sphinxsidebar input { | |||
| border: 1px solid #CCC; | |||
| font-family: Georgia, serif; | |||
| font-size: 1em; | |||
| } | |||
| div.sphinxsidebar hr { | |||
| border: none; | |||
| height: 1px; | |||
| color: #AAA; | |||
| background: #AAA; | |||
| text-align: left; | |||
| margin-left: 0; | |||
| width: 50%; | |||
| } | |||
| /* -- body styles ----------------------------------------------------------- */ | |||
| a { | |||
| color: #004B6B; | |||
| text-decoration: underline; | |||
| } | |||
| a:hover { | |||
| color: #6D4100; | |||
| text-decoration: underline; | |||
| } | |||
| div.body h1, | |||
| div.body h2, | |||
| div.body h3, | |||
| div.body h4, | |||
| div.body h5, | |||
| div.body h6 { | |||
| font-family: Georgia, serif; | |||
| font-weight: normal; | |||
| margin: 30px 0px 10px 0px; | |||
| padding: 0; | |||
| } | |||
| div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } | |||
| div.body h2 { font-size: 180%; } | |||
| div.body h3 { font-size: 150%; } | |||
| div.body h4 { font-size: 130%; } | |||
| div.body h5 { font-size: 100%; } | |||
| div.body h6 { font-size: 100%; } | |||
| a.headerlink { | |||
| color: #DDD; | |||
| padding: 0 4px; | |||
| text-decoration: none; | |||
| } | |||
| a.headerlink:hover { | |||
| color: #444; | |||
| background: #EAEAEA; | |||
| } | |||
| div.body p, div.body dd, div.body li { | |||
| line-height: 1.4em; | |||
| } | |||
| div.admonition { | |||
| margin: 20px 0px; | |||
| padding: 10px 30px; | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { | |||
| background-color: #FBFBFB; | |||
| border-bottom: 1px solid #fafafa; | |||
| } | |||
| div.admonition p.admonition-title { | |||
| font-family: Georgia, serif; | |||
| font-weight: normal; | |||
| font-size: 24px; | |||
| margin: 0 0 10px 0; | |||
| padding: 0; | |||
| line-height: 1; | |||
| } | |||
| div.admonition p.last { | |||
| margin-bottom: 0; | |||
| } | |||
| div.highlight { | |||
| background-color: #fff; | |||
| } | |||
| dt:target, .highlight { | |||
| background: #FAF3E8; | |||
| } | |||
| div.warning { | |||
| background-color: #FCC; | |||
| border: 1px solid #FAA; | |||
| } | |||
| div.danger { | |||
| background-color: #FCC; | |||
| border: 1px solid #FAA; | |||
| -moz-box-shadow: 2px 2px 4px #D52C2C; | |||
| -webkit-box-shadow: 2px 2px 4px #D52C2C; | |||
| box-shadow: 2px 2px 4px #D52C2C; | |||
| } | |||
| div.error { | |||
| background-color: #FCC; | |||
| border: 1px solid #FAA; | |||
| -moz-box-shadow: 2px 2px 4px #D52C2C; | |||
| -webkit-box-shadow: 2px 2px 4px #D52C2C; | |||
| box-shadow: 2px 2px 4px #D52C2C; | |||
| } | |||
| div.caution { | |||
| background-color: #FCC; | |||
| border: 1px solid #FAA; | |||
| } | |||
| div.attention { | |||
| background-color: #FCC; | |||
| border: 1px solid #FAA; | |||
| } | |||
| div.important { | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.note { | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.tip { | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.hint { | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.seealso { | |||
| background-color: #EEE; | |||
| border: 1px solid #CCC; | |||
| } | |||
| div.topic { | |||
| background-color: #EEE; | |||
| } | |||
| p.admonition-title { | |||
| display: inline; | |||
| } | |||
| p.admonition-title:after { | |||
| content: ":"; | |||
| } | |||
| pre, tt, code { | |||
| font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; | |||
| font-size: 0.9em; | |||
| } | |||
| .hll { | |||
| background-color: #FFC; | |||
| margin: 0 -12px; | |||
| padding: 0 12px; | |||
| display: block; | |||
| } | |||
| img.screenshot { | |||
| } | |||
| tt.descname, tt.descclassname, code.descname, code.descclassname { | |||
| font-size: 0.95em; | |||
| } | |||
| tt.descname, code.descname { | |||
| padding-right: 0.08em; | |||
| } | |||
| img.screenshot { | |||
| -moz-box-shadow: 2px 2px 4px #EEE; | |||
| -webkit-box-shadow: 2px 2px 4px #EEE; | |||
| box-shadow: 2px 2px 4px #EEE; | |||
| } | |||
| table.docutils { | |||
| border: 1px solid #888; | |||
| -moz-box-shadow: 2px 2px 4px #EEE; | |||
| -webkit-box-shadow: 2px 2px 4px #EEE; | |||
| box-shadow: 2px 2px 4px #EEE; | |||
| } | |||
| table.docutils td, table.docutils th { | |||
| border: 1px solid #888; | |||
| padding: 0.25em 0.7em; | |||
| } | |||
| table.field-list, table.footnote { | |||
| border: none; | |||
| -moz-box-shadow: none; | |||
| -webkit-box-shadow: none; | |||
| box-shadow: none; | |||
| } | |||
| table.footnote { | |||
| margin: 15px 0; | |||
| width: 100%; | |||
| border: 1px solid #EEE; | |||
| background: #FDFDFD; | |||
| font-size: 0.9em; | |||
| } | |||
| table.footnote + table.footnote { | |||
| margin-top: -15px; | |||
| border-top: none; | |||
| } | |||
| table.field-list th { | |||
| padding: 0 0.8em 0 0; | |||
| } | |||
| table.field-list td { | |||
| padding: 0; | |||
| } | |||
| table.field-list p { | |||
| margin-bottom: 0.8em; | |||
| } | |||
| /* Cloned from | |||
| * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 | |||
| */ | |||
| .field-name { | |||
| -moz-hyphens: manual; | |||
| -ms-hyphens: manual; | |||
| -webkit-hyphens: manual; | |||
| hyphens: manual; | |||
| } | |||
| table.footnote td.label { | |||
| width: .1px; | |||
| padding: 0.3em 0 0.3em 0.5em; | |||
| } | |||
| table.footnote td { | |||
| padding: 0.3em 0.5em; | |||
| } | |||
| dl { | |||
| margin: 0; | |||
| padding: 0; | |||
| } | |||
| dl dd { | |||
| margin-left: 30px; | |||
| } | |||
| blockquote { | |||
| margin: 0 0 0 30px; | |||
| padding: 0; | |||
| } | |||
| ul, ol { | |||
| /* Matches the 30px from the narrow-screen "li > ul" selector below */ | |||
| margin: 10px 0 10px 30px; | |||
| padding: 0; | |||
| } | |||
| pre { | |||
| background: #EEE; | |||
| padding: 7px 30px; | |||
| margin: 15px 0px; | |||
| line-height: 1.3em; | |||
| } | |||
| div.viewcode-block:target { | |||
| background: #ffd; | |||
| } | |||
| dl pre, blockquote pre, li pre { | |||
| margin-left: 0; | |||
| padding-left: 30px; | |||
| } | |||
| tt, code { | |||
| background-color: #ecf0f3; | |||
| color: #222; | |||
| /* padding: 1px 2px; */ | |||
| } | |||
| tt.xref, code.xref, a tt { | |||
| background-color: #FBFBFB; | |||
| border-bottom: 1px solid #fff; | |||
| } | |||
| a.reference { | |||
| text-decoration: none; | |||
| border-bottom: 1px dotted #004B6B; | |||
| } | |||
| /* Don't put an underline on images */ | |||
| a.image-reference, a.image-reference:hover { | |||
| border-bottom: none; | |||
| } | |||
| a.reference:hover { | |||
| border-bottom: 1px solid #6D4100; | |||
| } | |||
| a.footnote-reference { | |||
| text-decoration: none; | |||
| font-size: 0.7em; | |||
| vertical-align: top; | |||
| border-bottom: 1px dotted #004B6B; | |||
| } | |||
| a.footnote-reference:hover { | |||
| border-bottom: 1px solid #6D4100; | |||
| } | |||
| a:hover tt, a:hover code { | |||
| background: #EEE; | |||
| } | |||
| @media screen and (max-width: 870px) { | |||
| div.sphinxsidebar { | |||
| display: none; | |||
| } | |||
| div.document { | |||
| width: 100%; | |||
| } | |||
| div.documentwrapper { | |||
| margin-left: 0; | |||
| margin-top: 0; | |||
| margin-right: 0; | |||
| margin-bottom: 0; | |||
| } | |||
| div.bodywrapper { | |||
| margin-top: 0; | |||
| margin-right: 0; | |||
| margin-bottom: 0; | |||
| margin-left: 0; | |||
| } | |||
| ul { | |||
| margin-left: 0; | |||
| } | |||
| li > ul { | |||
| /* Matches the 30px from the "ul, ol" selector above */ | |||
| margin-left: 30px; | |||
| } | |||
| .document { | |||
| width: auto; | |||
| } | |||
| .footer { | |||
| width: auto; | |||
| } | |||
| .bodywrapper { | |||
| margin: 0; | |||
| } | |||
| .footer { | |||
| width: auto; | |||
| } | |||
| .github { | |||
| display: none; | |||
| } | |||
| } | |||
| @media screen and (max-width: 875px) { | |||
| body { | |||
| margin: 0; | |||
| padding: 20px 30px; | |||
| } | |||
| div.documentwrapper { | |||
| float: none; | |||
| background: #fff; | |||
| } | |||
| div.sphinxsidebar { | |||
| display: block; | |||
| float: none; | |||
| width: 102.5%; | |||
| margin: 50px -30px -20px -30px; | |||
| padding: 10px 20px; | |||
| background: #333; | |||
| color: #FFF; | |||
| } | |||
| div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, | |||
| div.sphinxsidebar h3 a { | |||
| color: #fff; | |||
| } | |||
| div.sphinxsidebar a { | |||
| color: #AAA; | |||
| } | |||
| div.sphinxsidebar p.logo { | |||
| display: none; | |||
| } | |||
| div.document { | |||
| width: 100%; | |||
| margin: 0; | |||
| } | |||
| div.footer { | |||
| display: none; | |||
| } | |||
| div.bodywrapper { | |||
| margin: 0; | |||
| } | |||
| div.body { | |||
| min-height: 0; | |||
| padding: 0; | |||
| } | |||
| .rtd_doc_footer { | |||
| display: none; | |||
| } | |||
| .document { | |||
| width: auto; | |||
| } | |||
| .footer { | |||
| width: auto; | |||
| } | |||
| .footer { | |||
| width: auto; | |||
| } | |||
| .github { | |||
| display: none; | |||
| } | |||
| } | |||
| /* misc. */ | |||
| .revsys-inline { | |||
| display: none!important; | |||
| } | |||
| /* Make nested-list/multi-paragraph items look better in Releases changelog | |||
| * pages. Without this, docutils' magical list fuckery causes inconsistent | |||
| * formatting between different release sub-lists. | |||
| */ | |||
| div#changelog > div.section > ul > li > p:only-child { | |||
| margin-bottom: 0; | |||
| } | |||
| /* Hide fugly table cell borders in ..bibliography:: directive output */ | |||
| table.docutils.citation, table.docutils.citation td, table.docutils.citation th { | |||
| border: none; | |||
| /* Below needed in some edge cases; if not applied, bottom shadows appear */ | |||
| -moz-box-shadow: none; | |||
| -webkit-box-shadow: none; | |||
| box-shadow: none; | |||
| } | |||
| /* relbar */ | |||
| .related { | |||
| line-height: 30px; | |||
| width: 100%; | |||
| font-size: 0.9rem; | |||
| } | |||
| .related.top { | |||
| border-bottom: 1px solid #EEE; | |||
| margin-bottom: 20px; | |||
| } | |||
| .related.bottom { | |||
| border-top: 1px solid #EEE; | |||
| } | |||
| .related ul { | |||
| padding: 0; | |||
| margin: 0; | |||
| list-style: none; | |||
| } | |||
| .related li { | |||
| display: inline; | |||
| } | |||
| nav#rellinks { | |||
| float: right; | |||
| } | |||
| nav#rellinks li+li:before { | |||
| content: "|"; | |||
| } | |||
| nav#breadcrumbs li+li:before { | |||
| content: "\00BB"; | |||
| } | |||
| /* Hide certain items when printing */ | |||
| @media print { | |||
| div.related { | |||
| display: none; | |||
| } | |||
| } | |||
| @ -0,0 +1,665 @@ | |||
| /* | |||
| * basic.css | |||
| * ~~~~~~~~~ | |||
| * | |||
| * Sphinx stylesheet -- basic theme. | |||
| * | |||
| * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. | |||
| * :license: BSD, see LICENSE for details. | |||
| * | |||
| */ | |||
| /* -- main layout ----------------------------------------------------------- */ | |||
| div.clearer { | |||
| clear: both; | |||
| } | |||
| /* -- relbar ---------------------------------------------------------------- */ | |||
| div.related { | |||
| width: 100%; | |||
| font-size: 90%; | |||
| } | |||
| div.related h3 { | |||
| display: none; | |||
| } | |||
| div.related ul { | |||
| margin: 0; | |||
| padding: 0 0 0 10px; | |||
| list-style: none; | |||
| } | |||
| div.related li { | |||
| display: inline; | |||
| } | |||
| div.related li.right { | |||
| float: right; | |||
| margin-right: 5px; | |||
| } | |||
| /* -- sidebar --------------------------------------------------------------- */ | |||
| div.sphinxsidebarwrapper { | |||
| padding: 10px 5px 0 10px; | |||
| } | |||
| div.sphinxsidebar { | |||
| float: left; | |||
| width: 230px; | |||
| margin-left: -100%; | |||
| font-size: 90%; | |||
| word-wrap: break-word; | |||
| overflow-wrap : break-word; | |||
| } | |||
| div.sphinxsidebar ul { | |||
| list-style: none; | |||
| } | |||
| div.sphinxsidebar ul ul, | |||
| div.sphinxsidebar ul.want-points { | |||
| margin-left: 20px; | |||
| list-style: square; | |||
| } | |||
| div.sphinxsidebar ul ul { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| } | |||
| div.sphinxsidebar form { | |||
| margin-top: 10px; | |||
| } | |||
| div.sphinxsidebar input { | |||
| border: 1px solid #98dbcc; | |||
| font-family: sans-serif; | |||
| font-size: 1em; | |||
| } | |||
| div.sphinxsidebar #searchbox input[type="text"] { | |||
| float: left; | |||
| width: 80%; | |||
| padding: 0.25em; | |||
| box-sizing: border-box; | |||
| } | |||
| div.sphinxsidebar #searchbox input[type="submit"] { | |||
| float: left; | |||
| width: 20%; | |||
| border-left: none; | |||
| padding: 0.25em; | |||
| box-sizing: border-box; | |||
| } | |||
| img { | |||
| border: 0; | |||
| max-width: 100%; | |||
| } | |||
| /* -- search page ----------------------------------------------------------- */ | |||
| ul.search { | |||
| margin: 10px 0 0 20px; | |||
| padding: 0; | |||
| } | |||
| ul.search li { | |||
| padding: 5px 0 5px 20px; | |||
| background-image: url(file.png); | |||
| background-repeat: no-repeat; | |||
| background-position: 0 7px; | |||
| } | |||
| ul.search li a { | |||
| font-weight: bold; | |||
| } | |||
| ul.search li div.context { | |||
| color: #888; | |||
| margin: 2px 0 0 30px; | |||
| text-align: left; | |||
| } | |||
| ul.keywordmatches li.goodmatch a { | |||
| font-weight: bold; | |||
| } | |||
| /* -- index page ------------------------------------------------------------ */ | |||
| table.contentstable { | |||
| width: 90%; | |||
| margin-left: auto; | |||
| margin-right: auto; | |||
| } | |||
| table.contentstable p.biglink { | |||
| line-height: 150%; | |||
| } | |||
| a.biglink { | |||
| font-size: 1.3em; | |||
| } | |||
| span.linkdescr { | |||
| font-style: italic; | |||
| padding-top: 5px; | |||
| font-size: 90%; | |||
| } | |||
| /* -- general index --------------------------------------------------------- */ | |||
| table.indextable { | |||
| width: 100%; | |||
| } | |||
| table.indextable td { | |||
| text-align: left; | |||
| vertical-align: top; | |||
| } | |||
| table.indextable ul { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| list-style-type: none; | |||
| } | |||
| table.indextable > tbody > tr > td > ul { | |||
| padding-left: 0em; | |||
| } | |||
| table.indextable tr.pcap { | |||
| height: 10px; | |||
| } | |||
| table.indextable tr.cap { | |||
| margin-top: 10px; | |||
| background-color: #f2f2f2; | |||
| } | |||
| img.toggler { | |||
| margin-right: 3px; | |||
| margin-top: 3px; | |||
| cursor: pointer; | |||
| } | |||
| div.modindex-jumpbox { | |||
| border-top: 1px solid #ddd; | |||
| border-bottom: 1px solid #ddd; | |||
| margin: 1em 0 1em 0; | |||
| padding: 0.4em; | |||
| } | |||
| div.genindex-jumpbox { | |||
| border-top: 1px solid #ddd; | |||
| border-bottom: 1px solid #ddd; | |||
| margin: 1em 0 1em 0; | |||
| padding: 0.4em; | |||
| } | |||
| /* -- domain module index --------------------------------------------------- */ | |||
| table.modindextable td { | |||
| padding: 2px; | |||
| border-collapse: collapse; | |||
| } | |||
| /* -- general body styles --------------------------------------------------- */ | |||
| div.body { | |||
| min-width: 450px; | |||
| max-width: 800px; | |||
| } | |||
| div.body p, div.body dd, div.body li, div.body blockquote { | |||
| -moz-hyphens: auto; | |||
| -ms-hyphens: auto; | |||
| -webkit-hyphens: auto; | |||
| hyphens: auto; | |||
| } | |||
| a.headerlink { | |||
| visibility: hidden; | |||
| } | |||
| h1:hover > a.headerlink, | |||
| h2:hover > a.headerlink, | |||
| h3:hover > a.headerlink, | |||
| h4:hover > a.headerlink, | |||
| h5:hover > a.headerlink, | |||
| h6:hover > a.headerlink, | |||
| dt:hover > a.headerlink, | |||
| caption:hover > a.headerlink, | |||
| p.caption:hover > a.headerlink, | |||
| div.code-block-caption:hover > a.headerlink { | |||
| visibility: visible; | |||
| } | |||
| div.body p.caption { | |||
| text-align: inherit; | |||
| } | |||
| div.body td { | |||
| text-align: left; | |||
| } | |||
| .first { | |||
| margin-top: 0 !important; | |||
| } | |||
| p.rubric { | |||
| margin-top: 30px; | |||
| font-weight: bold; | |||
| } | |||
| img.align-left, .figure.align-left, object.align-left { | |||
| clear: left; | |||
| float: left; | |||
| margin-right: 1em; | |||
| } | |||
| img.align-right, .figure.align-right, object.align-right { | |||
| clear: right; | |||
| float: right; | |||
| margin-left: 1em; | |||
| } | |||
| img.align-center, .figure.align-center, object.align-center { | |||
| display: block; | |||
| margin-left: auto; | |||
| margin-right: auto; | |||
| } | |||
| .align-left { | |||
| text-align: left; | |||
| } | |||
| .align-center { | |||
| text-align: center; | |||
| } | |||
| .align-right { | |||
| text-align: right; | |||
| } | |||
| /* -- sidebars -------------------------------------------------------------- */ | |||
| div.sidebar { | |||
| margin: 0 0 0.5em 1em; | |||
| border: 1px solid #ddb; | |||
| padding: 7px 7px 0 7px; | |||
| background-color: #ffe; | |||
| width: 40%; | |||
| float: right; | |||
| } | |||
| p.sidebar-title { | |||
| font-weight: bold; | |||
| } | |||
| /* -- topics ---------------------------------------------------------------- */ | |||
| div.topic { | |||
| border: 1px solid #ccc; | |||
| padding: 7px 7px 0 7px; | |||
| margin: 10px 0 10px 0; | |||
| } | |||
| p.topic-title { | |||
| font-size: 1.1em; | |||
| font-weight: bold; | |||
| margin-top: 10px; | |||
| } | |||
| /* -- admonitions ----------------------------------------------------------- */ | |||
| div.admonition { | |||
| margin-top: 10px; | |||
| margin-bottom: 10px; | |||
| padding: 7px; | |||
| } | |||
| div.admonition dt { | |||
| font-weight: bold; | |||
| } | |||
| div.admonition dl { | |||
| margin-bottom: 0; | |||
| } | |||
| p.admonition-title { | |||
| margin: 0px 10px 5px 0px; | |||
| font-weight: bold; | |||
| } | |||
| div.body p.centered { | |||
| text-align: center; | |||
| margin-top: 25px; | |||
| } | |||
| /* -- tables ---------------------------------------------------------------- */ | |||
| table.docutils { | |||
| border: 0; | |||
| border-collapse: collapse; | |||
| } | |||
| table.align-center { | |||
| margin-left: auto; | |||
| margin-right: auto; | |||
| } | |||
| table caption span.caption-number { | |||
| font-style: italic; | |||
| } | |||
| table caption span.caption-text { | |||
| } | |||
| table.docutils td, table.docutils th { | |||
| padding: 1px 8px 1px 5px; | |||
| border-top: 0; | |||
| border-left: 0; | |||
| border-right: 0; | |||
| border-bottom: 1px solid #aaa; | |||
| } | |||
| table.footnote td, table.footnote th { | |||
| border: 0 !important; | |||
| } | |||
| th { | |||
| text-align: left; | |||
| padding-right: 5px; | |||
| } | |||
| table.citation { | |||
| border-left: solid 1px gray; | |||
| margin-left: 1px; | |||
| } | |||
| table.citation td { | |||
| border-bottom: none; | |||
| } | |||
| /* -- figures --------------------------------------------------------------- */ | |||
| div.figure { | |||
| margin: 0.5em; | |||
| padding: 0.5em; | |||
| } | |||
| div.figure p.caption { | |||
| padding: 0.3em; | |||
| } | |||
| div.figure p.caption span.caption-number { | |||
| font-style: italic; | |||
| } | |||
| div.figure p.caption span.caption-text { | |||
| } | |||
| /* -- field list styles ----------------------------------------------------- */ | |||
| table.field-list td, table.field-list th { | |||
| border: 0 !important; | |||
| } | |||
| .field-list ul { | |||
| margin: 0; | |||
| padding-left: 1em; | |||
| } | |||
| .field-list p { | |||
| margin: 0; | |||
| } | |||
| .field-name { | |||
| -moz-hyphens: manual; | |||
| -ms-hyphens: manual; | |||
| -webkit-hyphens: manual; | |||
| hyphens: manual; | |||
| } | |||
| /* -- other body styles ----------------------------------------------------- */ | |||
| ol.arabic { | |||
| list-style: decimal; | |||
| } | |||
| ol.loweralpha { | |||
| list-style: lower-alpha; | |||
| } | |||
| ol.upperalpha { | |||
| list-style: upper-alpha; | |||
| } | |||
| ol.lowerroman { | |||
| list-style: lower-roman; | |||
| } | |||
| ol.upperroman { | |||
| list-style: upper-roman; | |||
| } | |||
| dl { | |||
| margin-bottom: 15px; | |||
| } | |||
| dd p { | |||
| margin-top: 0px; | |||
| } | |||
| dd ul, dd table { | |||
| margin-bottom: 10px; | |||
| } | |||
| dd { | |||
| margin-top: 3px; | |||
| margin-bottom: 10px; | |||
| margin-left: 30px; | |||
| } | |||
| dt:target, span.highlighted { | |||
| background-color: #fbe54e; | |||
| } | |||
| rect.highlighted { | |||
| fill: #fbe54e; | |||
| } | |||
| dl.glossary dt { | |||
| font-weight: bold; | |||
| font-size: 1.1em; | |||
| } | |||
| .optional { | |||
| font-size: 1.3em; | |||
| } | |||
| .sig-paren { | |||
| font-size: larger; | |||
| } | |||
| .versionmodified { | |||
| font-style: italic; | |||
| } | |||
| .system-message { | |||
| background-color: #fda; | |||
| padding: 5px; | |||
| border: 3px solid red; | |||
| } | |||
| .footnote:target { | |||
| background-color: #ffa; | |||
| } | |||
| .line-block { | |||
| display: block; | |||
| margin-top: 1em; | |||
| margin-bottom: 1em; | |||
| } | |||
| .line-block .line-block { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| margin-left: 1.5em; | |||
| } | |||
| .guilabel, .menuselection { | |||
| font-family: sans-serif; | |||
| } | |||
| .accelerator { | |||
| text-decoration: underline; | |||
| } | |||
| .classifier { | |||
| font-style: oblique; | |||
| } | |||
| abbr, acronym { | |||
| border-bottom: dotted 1px; | |||
| cursor: help; | |||
| } | |||
| /* -- code displays --------------------------------------------------------- */ | |||
| pre { | |||
| overflow: auto; | |||
| overflow-y: hidden; /* fixes display issues on Chrome browsers */ | |||
| } | |||
| span.pre { | |||
| -moz-hyphens: none; | |||
| -ms-hyphens: none; | |||
| -webkit-hyphens: none; | |||
| hyphens: none; | |||
| } | |||
| td.linenos pre { | |||
| padding: 5px 0px; | |||
| border: 0; | |||
| background-color: transparent; | |||
| color: #aaa; | |||
| } | |||
| table.highlighttable { | |||
| margin-left: 0.5em; | |||
| } | |||
| table.highlighttable td { | |||
| padding: 0 0.5em 0 0.5em; | |||
| } | |||
| div.code-block-caption { | |||
| padding: 2px 5px; | |||
| font-size: small; | |||
| } | |||
| div.code-block-caption code { | |||
| background-color: transparent; | |||
| } | |||
| div.code-block-caption + div > div.highlight > pre { | |||
| margin-top: 0; | |||
| } | |||
| div.code-block-caption span.caption-number { | |||
| padding: 0.1em 0.3em; | |||
| font-style: italic; | |||
| } | |||
| div.code-block-caption span.caption-text { | |||
| } | |||
| div.literal-block-wrapper { | |||
| padding: 1em 1em 0; | |||
| } | |||
| div.literal-block-wrapper div.highlight { | |||
| margin: 0; | |||
| } | |||
| code.descname { | |||
| background-color: transparent; | |||
| font-weight: bold; | |||
| font-size: 1.2em; | |||
| } | |||
| code.descclassname { | |||
| background-color: transparent; | |||
| } | |||
| code.xref, a code { | |||
| background-color: transparent; | |||
| font-weight: bold; | |||
| } | |||
| h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { | |||
| background-color: transparent; | |||
| } | |||
| .viewcode-link { | |||
| float: right; | |||
| } | |||
| .viewcode-back { | |||
| float: right; | |||
| font-family: sans-serif; | |||
| } | |||
| div.viewcode-block:target { | |||
| margin: -1px -10px; | |||
| padding: 0 10px; | |||
| } | |||
| /* -- math display ---------------------------------------------------------- */ | |||
| img.math { | |||
| vertical-align: middle; | |||
| } | |||
| div.body div.math p { | |||
| text-align: center; | |||
| } | |||
| span.eqno { | |||
| float: right; | |||
| } | |||
| span.eqno a.headerlink { | |||
| position: relative; | |||
| left: 0px; | |||
| z-index: 1; | |||
| } | |||
| div.math:hover a.headerlink { | |||
| visibility: visible; | |||
| } | |||
| /* -- printout stylesheet --------------------------------------------------- */ | |||
| @media print { | |||
| div.document, | |||
| div.documentwrapper, | |||
| div.bodywrapper { | |||
| margin: 0 !important; | |||
| width: 100%; | |||
| } | |||
| div.sphinxsidebar, | |||
| div.related, | |||
| div.footer, | |||
| #top-link { | |||
| display: none; | |||
| } | |||
| } | |||
| @ -0,0 +1 @@ | |||
| /* This file intentionally left blank. */ | |||
| @ -0,0 +1,313 @@ | |||
| /* | |||
| * doctools.js | |||
| * ~~~~~~~~~~~ | |||
| * | |||
| * Sphinx JavaScript utilities for all documentation. | |||
| * | |||
| * :copyright: Copyright 2007-2018 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 | |||
| */ | |||
| jQuery.urldecode = function(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 bbox = span.getBBox(); | |||
| var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); | |||
| 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); | |||
| var parentOfText = node.parentNode.parentNode; | |||
| 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(); | |||
| }, | |||
| /** | |||
| * 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() { | |||
| $('<a class="headerlink">\u00B6</a>'). | |||
| attr('href', '#' + this.id). | |||
| attr('title', _('Permalink to this headline')). | |||
| appendTo(this); | |||
| }); | |||
| $('dt[id]').each(function() { | |||
| $('<a class="headerlink">\u00B6</a>'). | |||
| 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); | |||
| $('<p class="highlight-link"><a href="javascript:Documentation.' + | |||
| 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') | |||
| .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).keyup(function(event) { | |||
| var activeElementType = document.activeElement.tagName; | |||
| // don't navigate when in search box or textarea | |||
| if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { | |||
| switch (event.keyCode) { | |||
| case 37: // left | |||
| var prevHref = $('link[rel="prev"]').prop('href'); | |||
| if (prevHref) { | |||
| window.location.href = prevHref; | |||
| return false; | |||
| } | |||
| case 39: // right | |||
| var nextHref = $('link[rel="next"]').prop('href'); | |||
| if (nextHref) { | |||
| window.location.href = nextHref; | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| }; | |||
| // quick alias for translations | |||
| _ = Documentation.gettext; | |||
| $(document).ready(function() { | |||
| Documentation.init(); | |||
| }); | |||
| @ -0,0 +1,9 @@ | |||
| var DOCUMENTATION_OPTIONS = { | |||
| URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), | |||
| VERSION: '', | |||
| LANGUAGE: 'None', | |||
| COLLAPSE_INDEX: false, | |||
| FILE_SUFFIX: '.html', | |||
| HAS_SOURCE: true, | |||
| SOURCELINK_SUFFIX: '.txt' | |||
| }; | |||
| @ -0,0 +1,69 @@ | |||
| .highlight .hll { background-color: #ffffcc } | |||
| .highlight { background: #eeffcc; } | |||
| .highlight .c { color: #408090; font-style: italic } /* Comment */ | |||
| .highlight .err { border: 1px solid #FF0000 } /* Error */ | |||
| .highlight .k { color: #007020; font-weight: bold } /* Keyword */ | |||
| .highlight .o { color: #666666 } /* Operator */ | |||
| .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ | |||
| .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ | |||
| .highlight .cp { color: #007020 } /* Comment.Preproc */ | |||
| .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ | |||
| .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ | |||
| .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ | |||
| .highlight .gd { color: #A00000 } /* Generic.Deleted */ | |||
| .highlight .ge { font-style: italic } /* Generic.Emph */ | |||
| .highlight .gr { color: #FF0000 } /* Generic.Error */ | |||
| .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ | |||
| .highlight .gi { color: #00A000 } /* Generic.Inserted */ | |||
| .highlight .go { color: #333333 } /* Generic.Output */ | |||
| .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ | |||
| .highlight .gs { font-weight: bold } /* Generic.Strong */ | |||
| .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ | |||
| .highlight .gt { color: #0044DD } /* Generic.Traceback */ | |||
| .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ | |||
| .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ | |||
| .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ | |||
| .highlight .kp { color: #007020 } /* Keyword.Pseudo */ | |||
| .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ | |||
| .highlight .kt { color: #902000 } /* Keyword.Type */ | |||
| .highlight .m { color: #208050 } /* Literal.Number */ | |||
| .highlight .s { color: #4070a0 } /* Literal.String */ | |||
| .highlight .na { color: #4070a0 } /* Name.Attribute */ | |||
| .highlight .nb { color: #007020 } /* Name.Builtin */ | |||
| .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ | |||
| .highlight .no { color: #60add5 } /* Name.Constant */ | |||
| .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ | |||
| .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ | |||
| .highlight .ne { color: #007020 } /* Name.Exception */ | |||
| .highlight .nf { color: #06287e } /* Name.Function */ | |||
| .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ | |||
| .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ | |||
| .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ | |||
| .highlight .nv { color: #bb60d5 } /* Name.Variable */ | |||
| .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ | |||
| .highlight .w { color: #bbbbbb } /* Text.Whitespace */ | |||
| .highlight .mb { color: #208050 } /* Literal.Number.Bin */ | |||
| .highlight .mf { color: #208050 } /* Literal.Number.Float */ | |||
| .highlight .mh { color: #208050 } /* Literal.Number.Hex */ | |||
| .highlight .mi { color: #208050 } /* Literal.Number.Integer */ | |||
| .highlight .mo { color: #208050 } /* Literal.Number.Oct */ | |||
| .highlight .sa { color: #4070a0 } /* Literal.String.Affix */ | |||
| .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ | |||
| .highlight .sc { color: #4070a0 } /* Literal.String.Char */ | |||
| .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ | |||
| .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ | |||
| .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ | |||
| .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ | |||
| .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ | |||
| .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ | |||
| .highlight .sx { color: #c65d09 } /* Literal.String.Other */ | |||
| .highlight .sr { color: #235388 } /* Literal.String.Regex */ | |||
| .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ | |||
| .highlight .ss { color: #517918 } /* Literal.String.Symbol */ | |||
| .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ | |||
| .highlight .fm { color: #06287e } /* Name.Function.Magic */ | |||
| .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ | |||
| .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ | |||
| .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ | |||
| .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ | |||
| .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ | |||
| @ -0,0 +1,761 @@ | |||
| /* | |||
| * searchtools.js_t | |||
| * ~~~~~~~~~~~~~~~~ | |||
| * | |||
| * Sphinx JavaScript utilities for the full-text search. | |||
| * | |||
| * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. | |||
| * :license: BSD, see LICENSE for details. | |||
| * | |||
| */ | |||
| /* Non-minified version JS is _stemmer.js if file is provided */ | |||
| /** | |||
| * Porter Stemmer | |||
| */ | |||
| var Stemmer = function() { | |||
| var step2list = { | |||
| ational: 'ate', | |||
| tional: 'tion', | |||
| enci: 'ence', | |||
| anci: 'ance', | |||
| izer: 'ize', | |||
| bli: 'ble', | |||
| alli: 'al', | |||
| entli: 'ent', | |||
| eli: 'e', | |||
| ousli: 'ous', | |||
| ization: 'ize', | |||
| ation: 'ate', | |||
| ator: 'ate', | |||
| alism: 'al', | |||
| iveness: 'ive', | |||
| fulness: 'ful', | |||
| ousness: 'ous', | |||
| aliti: 'al', | |||
| iviti: 'ive', | |||
| biliti: 'ble', | |||
| logi: 'log' | |||
| }; | |||
| var step3list = { | |||
| icate: 'ic', | |||
| ative: '', | |||
| alize: 'al', | |||
| iciti: 'ic', | |||
| ical: 'ic', | |||
| ful: '', | |||
| ness: '' | |||
| }; | |||
| var c = "[^aeiou]"; // consonant | |||
| var v = "[aeiouy]"; // vowel | |||
| var C = c + "[^aeiouy]*"; // consonant sequence | |||
| var V = v + "[aeiou]*"; // vowel sequence | |||
| var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 | |||
| 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; | |||
| } | |||
| } | |||
| /** | |||
| * 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, | |||
| // query found in terms | |||
| term: 5 | |||
| }; | |||
| 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; | |||
| } | |||
| /** | |||
| * Search Module | |||
| */ | |||
| var Search = { | |||
| _index : null, | |||
| _queued_query : null, | |||
| _pulse_status : -1, | |||
| 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 = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out); | |||
| this.dots = $('<span></span>').appendTo(this.title); | |||
| this.status = $('<p style="display: none"></p>').appendTo(this.out); | |||
| this.output = $('<ul class="search"/>').appendTo(this.out); | |||
| $('#search-progress').text(_('Preparing search...')); | |||
| this.startPulse(); | |||
| // index already loaded, the browser was quick! | |||
| if (this.hasIndex()) | |||
| this.query(query); | |||
| else | |||
| this.deferQuery(query); | |||
| }, | |||
| /** | |||
| * execute search (requires search index to be loaded) | |||
| */ | |||
| query : function(query) { | |||
| var i; | |||
| var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; | |||
| // stem the searchterms and add them to the correct list | |||
| var stemmer = new Stemmer(); | |||
| var searchterms = []; | |||
| var excluded = []; | |||
| var hlterms = []; | |||
| var tmp = splitQuery(query); | |||
| var objectterms = []; | |||
| for (i = 0; i < tmp.length; i++) { | |||
| if (tmp[i] !== "") { | |||
| objectterms.push(tmp[i].toLowerCase()); | |||
| } | |||
| if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) || | |||
| tmp[i] === "") { | |||
| // skip this "word" | |||
| continue; | |||
| } | |||
| // stem the word | |||
| var word = stemmer.stemWord(tmp[i].toLowerCase()); | |||
| // prevent stemmer from cutting word smaller than two chars | |||
| if(word.length < 3 && tmp[i].length >= 3) { | |||
| word = tmp[i]; | |||
| } | |||
| var toAppend; | |||
| // select the correct list | |||
| if (word[0] == '-') { | |||
| toAppend = excluded; | |||
| word = word.substr(1); | |||
| } | |||
| else { | |||
| toAppend = searchterms; | |||
| hlterms.push(tmp[i].toLowerCase()); | |||
| } | |||
| // only add if not already in the list | |||
| if (!$u.contains(toAppend, word)) | |||
| toAppend.push(word); | |||
| } | |||
| var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); | |||
| // console.debug('SEARCH: searching for:'); | |||
| // console.info('required: ', searchterms); | |||
| // console.info('excluded: ', excluded); | |||
| // prepare search | |||
| var terms = this._index.terms; | |||
| var titleterms = this._index.titleterms; | |||
| // array of [filename, title, anchor, descr, score] | |||
| var results = []; | |||
| $('#search-progress').empty(); | |||
| // lookup as object | |||
| for (i = 0; i < objectterms.length; i++) { | |||
| var others = [].concat(objectterms.slice(0, i), | |||
| objectterms.slice(i+1, objectterms.length)); | |||
| results = results.concat(this.performObjectSearch(objectterms[i], others)); | |||
| } | |||
| // lookup as search terms in fulltext | |||
| results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms)); | |||
| // let the scorer override scores with a custom scoring function | |||
| if (Scorer.score) { | |||
| for (i = 0; i < results.length; i++) | |||
| results[i][4] = Scorer.score(results[i]); | |||
| } | |||
| // now sort the results by score (in opposite order of appearance, since the | |||
| // display function below uses pop() to retrieve items) and then | |||
| // alphabetically | |||
| results.sort(function(a, b) { | |||
| var left = a[4]; | |||
| var right = b[4]; | |||
| if (left > right) { | |||
| return 1; | |||
| } else if (left < right) { | |||
| return -1; | |||
| } else { | |||
| // same score: sort alphabetically | |||
| left = a[1].toLowerCase(); | |||
| right = b[1].toLowerCase(); | |||
| return (left > right) ? -1 : ((left < right) ? 1 : 0); | |||
| } | |||
| }); | |||
| // for debugging | |||
| //Search.lastresults = results.slice(); // a copy | |||
| //console.info('search results:', Search.lastresults); | |||
| // print the results | |||
| var resultCount = results.length; | |||
| function displayNextItem() { | |||
| // results left, load the summary and display it | |||
| if (results.length) { | |||
| var item = results.pop(); | |||
| var listItem = $('<li style="display:none"></li>'); | |||
| if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { | |||
| // dirhtml builder | |||
| var dirname = item[0] + '/'; | |||
| if (dirname.match(/\/index\/$/)) { | |||
| dirname = dirname.substring(0, dirname.length-6); | |||
| } else if (dirname == 'index/') { | |||
| dirname = ''; | |||
| } | |||
| listItem.append($('<a/>').attr('href', | |||
| DOCUMENTATION_OPTIONS.URL_ROOT + dirname + | |||
| highlightstring + item[2]).html(item[1])); | |||
| } else { | |||
| // normal html builders | |||
| listItem.append($('<a/>').attr('href', | |||
| item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + | |||
| highlightstring + item[2]).html(item[1])); | |||
| } | |||
| if (item[3]) { | |||
| listItem.append($('<span> (' + item[3] + ')</span>')); | |||
| Search.output.append(listItem); | |||
| listItem.slideDown(5, function() { | |||
| displayNextItem(); | |||
| }); | |||
| } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { | |||
| var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX; | |||
| if (suffix === undefined) { | |||
| suffix = '.txt'; | |||
| } | |||
| $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix), | |||
| dataType: "text", | |||
| complete: function(jqxhr, textstatus) { | |||
| var data = jqxhr.responseText; | |||
| if (data !== '' && data !== undefined) { | |||
| listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); | |||
| } | |||
| Search.output.append(listItem); | |||
| listItem.slideDown(5, function() { | |||
| displayNextItem(); | |||
| }); | |||
| }}); | |||
| } else { | |||
| // no source available, just display title | |||
| Search.output.append(listItem); | |||
| listItem.slideDown(5, function() { | |||
| displayNextItem(); | |||
| }); | |||
| } | |||
| } | |||
| // search finished, update title and status message | |||
| else { | |||
| Search.stopPulse(); | |||
| Search.title.text(_('Search Results')); | |||
| if (!resultCount) | |||
| Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.')); | |||
| else | |||
| Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount)); | |||
| Search.status.fadeIn(500); | |||
| } | |||
| } | |||
| displayNextItem(); | |||
| }, | |||
| /** | |||
| * search for object names | |||
| */ | |||
| performObjectSearch : function(object, otherterms) { | |||
| var filenames = this._index.filenames; | |||
| var docnames = this._index.docnames; | |||
| var objects = this._index.objects; | |||
| var objnames = this._index.objnames; | |||
| var titles = this._index.titles; | |||
| var i; | |||
| var results = []; | |||
| for (var prefix in objects) { | |||
| for (var name in objects[prefix]) { | |||
| var fullname = (prefix ? prefix + '.' : '') + name; | |||
| if (fullname.toLowerCase().indexOf(object) > -1) { | |||
| var score = 0; | |||
| var parts = fullname.split('.'); | |||
| // check for different match types: exact matches of full name or | |||
| // "last name" (i.e. last dotted part) | |||
| if (fullname == object || parts[parts.length - 1] == object) { | |||
| score += Scorer.objNameMatch; | |||
| // matches in last name | |||
| } else if (parts[parts.length - 1].indexOf(object) > -1) { | |||
| score += Scorer.objPartialMatch; | |||
| } | |||
| var match = objects[prefix][name]; | |||
| var objname = objnames[match[1]][2]; | |||
| var title = titles[match[0]]; | |||
| // If more than one term searched for, we require other words to be | |||
| // found in the name/title/description | |||
| if (otherterms.length > 0) { | |||
| var haystack = (prefix + ' ' + name + ' ' + | |||
| objname + ' ' + title).toLowerCase(); | |||
| var allfound = true; | |||
| for (i = 0; i < otherterms.length; i++) { | |||
| if (haystack.indexOf(otherterms[i]) == -1) { | |||
| allfound = false; | |||
| break; | |||
| } | |||
| } | |||
| if (!allfound) { | |||
| continue; | |||
| } | |||
| } | |||
| var descr = objname + _(', in ') + title; | |||
| var anchor = match[3]; | |||
| if (anchor === '') | |||
| anchor = fullname; | |||
| else if (anchor == '-') | |||
| anchor = objnames[match[1]][1] + '-' + fullname; | |||
| // add custom score for some objects according to scorer | |||
| if (Scorer.objPrio.hasOwnProperty(match[2])) { | |||
| score += Scorer.objPrio[match[2]]; | |||
| } else { | |||
| score += Scorer.objPrioDefault; | |||
| } | |||
| results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]); | |||
| } | |||
| } | |||
| } | |||
| return results; | |||
| }, | |||
| /** | |||
| * search for full-text terms in the index | |||
| */ | |||
| performTermsSearch : function(searchterms, excluded, terms, titleterms) { | |||
| var docnames = this._index.docnames; | |||
| var filenames = this._index.filenames; | |||
| var titles = this._index.titles; | |||
| var i, j, file; | |||
| var fileMap = {}; | |||
| var scoreMap = {}; | |||
| var results = []; | |||
| // perform the search on the required terms | |||
| for (i = 0; i < searchterms.length; i++) { | |||
| var word = searchterms[i]; | |||
| var files = []; | |||
| var _o = [ | |||
| {files: terms[word], score: Scorer.term}, | |||
| {files: titleterms[word], score: Scorer.title} | |||
| ]; | |||
| // no match but word was a required one | |||
| if ($u.every(_o, function(o){return o.files === undefined;})) { | |||
| break; | |||
| } | |||
| // found search word in contents | |||
| $u.each(_o, function(o) { | |||
| var _files = o.files; | |||
| if (_files === undefined) | |||
| return | |||
| if (_files.length === undefined) | |||
| _files = [_files]; | |||
| files = files.concat(_files); | |||
| // set score for the word in each file to Scorer.term | |||
| for (j = 0; j < _files.length; j++) { | |||
| file = _files[j]; | |||
| if (!(file in scoreMap)) | |||
| scoreMap[file] = {} | |||
| scoreMap[file][word] = o.score; | |||
| } | |||
| }); | |||
| // create the mapping | |||
| for (j = 0; j < files.length; j++) { | |||
| file = files[j]; | |||
| if (file in fileMap) | |||
| fileMap[file].push(word); | |||
| else | |||
| fileMap[file] = [word]; | |||
| } | |||
| } | |||
| // now check if the files don't contain excluded terms | |||
| for (file in fileMap) { | |||
| var valid = true; | |||
| // check if all requirements are matched | |||
| if (fileMap[file].length != searchterms.length) | |||
| continue; | |||
| // ensure that none of the excluded terms is in the search result | |||
| for (i = 0; i < excluded.length; i++) { | |||
| if (terms[excluded[i]] == file || | |||
| titleterms[excluded[i]] == file || | |||
| $u.contains(terms[excluded[i]] || [], file) || | |||
| $u.contains(titleterms[excluded[i]] || [], file)) { | |||
| valid = false; | |||
| break; | |||
| } | |||
| } | |||
| // if we have still a valid result we can add it to the result list | |||
| if (valid) { | |||
| // select one (max) score for the file. | |||
| // for better ranking, we should calculate ranking by using words statistics like basic tf-idf... | |||
| var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]})); | |||
| results.push([docnames[file], titles[file], '', null, score, filenames[file]]); | |||
| } | |||
| } | |||
| return results; | |||
| }, | |||
| /** | |||
| * helper function to return a node containing the | |||
| * search summary for a given text. keywords is a list | |||
| * of stemmed words, hlwords is the list of normal, unstemmed | |||
| * words. the first one is used to find the occurrence, the | |||
| * latter for highlighting it. | |||
| */ | |||
| makeSearchSummary : function(text, keywords, hlwords) { | |||
| var textLower = text.toLowerCase(); | |||
| var start = 0; | |||
| $.each(keywords, function() { | |||
| var i = textLower.indexOf(this.toLowerCase()); | |||
| if (i > -1) | |||
| start = i; | |||
| }); | |||
| start = Math.max(start - 120, 0); | |||
| var excerpt = ((start > 0) ? '...' : '') + | |||
| $.trim(text.substr(start, 240)) + | |||
| ((start + 240 - text.length) ? '...' : ''); | |||
| var rv = $('<div class="context"></div>').text(excerpt); | |||
| $.each(hlwords, function() { | |||
| rv = rv.highlightText(this, 'highlighted'); | |||
| }); | |||
| return rv; | |||
| } | |||
| }; | |||
| $(document).ready(function() { | |||
| Search.init(); | |||
| }); | |||
| @ -0,0 +1,999 @@ | |||
| // Underscore.js 1.3.1 | |||
| // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. | |||
| // Underscore is freely distributable under the MIT license. | |||
| // Portions of Underscore are inspired or borrowed from Prototype, | |||
| // Oliver Steele's Functional, and John Resig's Micro-Templating. | |||
| // For all details and documentation: | |||
| // http://documentcloud.github.com/underscore | |||
| (function() { | |||
| // Baseline setup | |||
| // -------------- | |||
| // Establish the root object, `window` in the browser, or `global` on the server. | |||
| var root = this; | |||
| // Save the previous value of the `_` variable. | |||
| var previousUnderscore = root._; | |||
| // Establish the object that gets returned to break out of a loop iteration. | |||
| var breaker = {}; | |||
| // Save bytes in the minified (but not gzipped) version: | |||
| var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; | |||
| // Create quick reference variables for speed access to core prototypes. | |||
| var slice = ArrayProto.slice, | |||
| unshift = ArrayProto.unshift, | |||
| toString = ObjProto.toString, | |||
| hasOwnProperty = ObjProto.hasOwnProperty; | |||
| // All **ECMAScript 5** native function implementations that we hope to use | |||
| // are declared here. | |||
| var | |||
| nativeForEach = ArrayProto.forEach, | |||
| nativeMap = ArrayProto.map, | |||
| nativeReduce = ArrayProto.reduce, | |||
| nativeReduceRight = ArrayProto.reduceRight, | |||
| nativeFilter = ArrayProto.filter, | |||
| nativeEvery = ArrayProto.every, | |||
| nativeSome = ArrayProto.some, | |||
| nativeIndexOf = ArrayProto.indexOf, | |||
| nativeLastIndexOf = ArrayProto.lastIndexOf, | |||
| nativeIsArray = Array.isArray, | |||
| nativeKeys = Object.keys, | |||
| nativeBind = FuncProto.bind; | |||
| // Create a safe reference to the Underscore object for use below. | |||
| var _ = function(obj) { return new wrapper(obj); }; | |||
| // Export the Underscore object for **Node.js**, with | |||
| // backwards-compatibility for the old `require()` API. If we're in | |||
| // the browser, add `_` as a global object via a string identifier, | |||
| // for Closure Compiler "advanced" mode. | |||
| if (typeof exports !== 'undefined') { | |||
| if (typeof module !== 'undefined' && module.exports) { | |||
| exports = module.exports = _; | |||
| } | |||
| exports._ = _; | |||
| } else { | |||
| root['_'] = _; | |||
| } | |||
| // Current version. | |||
| _.VERSION = '1.3.1'; | |||
| // Collection Functions | |||
| // -------------------- | |||
| // The cornerstone, an `each` implementation, aka `forEach`. | |||
| // Handles objects with the built-in `forEach`, arrays, and raw objects. | |||
| // Delegates to **ECMAScript 5**'s native `forEach` if available. | |||
| var each = _.each = _.forEach = function(obj, iterator, context) { | |||
| if (obj == null) return; | |||
| if (nativeForEach && obj.forEach === nativeForEach) { | |||
| obj.forEach(iterator, context); | |||
| } else if (obj.length === +obj.length) { | |||
| for (var i = 0, l = obj.length; i < l; i++) { | |||
| if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; | |||
| } | |||
| } else { | |||
| for (var key in obj) { | |||
| if (_.has(obj, key)) { | |||
| if (iterator.call(context, obj[key], key, obj) === breaker) return; | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| // Return the results of applying the iterator to each element. | |||
| // Delegates to **ECMAScript 5**'s native `map` if available. | |||
| _.map = _.collect = function(obj, iterator, context) { | |||
| var results = []; | |||
| if (obj == null) return results; | |||
| if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); | |||
| each(obj, function(value, index, list) { | |||
| results[results.length] = iterator.call(context, value, index, list); | |||
| }); | |||
| if (obj.length === +obj.length) results.length = obj.length; | |||
| return results; | |||
| }; | |||
| // **Reduce** builds up a single result from a list of values, aka `inject`, | |||
| // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. | |||
| _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { | |||
| var initial = arguments.length > 2; | |||
| if (obj == null) obj = []; | |||
| if (nativeReduce && obj.reduce === nativeReduce) { | |||
| if (context) iterator = _.bind(iterator, context); | |||
| return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); | |||
| } | |||
| each(obj, function(value, index, list) { | |||
| if (!initial) { | |||
| memo = value; | |||
| initial = true; | |||
| } else { | |||
| memo = iterator.call(context, memo, value, index, list); | |||
| } | |||
| }); | |||
| if (!initial) throw new TypeError('Reduce of empty array with no initial value'); | |||
| return memo; | |||
| }; | |||
| // The right-associative version of reduce, also known as `foldr`. | |||
| // Delegates to **ECMAScript 5**'s native `reduceRight` if available. | |||
| _.reduceRight = _.foldr = function(obj, iterator, memo, context) { | |||
| var initial = arguments.length > 2; | |||
| if (obj == null) obj = []; | |||
| if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { | |||
| if (context) iterator = _.bind(iterator, context); | |||
| return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); | |||
| } | |||
| var reversed = _.toArray(obj).reverse(); | |||
| if (context && !initial) iterator = _.bind(iterator, context); | |||
| return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); | |||
| }; | |||
| // Return the first value which passes a truth test. Aliased as `detect`. | |||
| _.find = _.detect = function(obj, iterator, context) { | |||
| var result; | |||
| any(obj, function(value, index, list) { | |||
| if (iterator.call(context, value, index, list)) { | |||
| result = value; | |||
| return true; | |||
| } | |||
| }); | |||
| return result; | |||
| }; | |||
| // Return all the elements that pass a truth test. | |||
| // Delegates to **ECMAScript 5**'s native `filter` if available. | |||
| // Aliased as `select`. | |||
| _.filter = _.select = function(obj, iterator, context) { | |||
| var results = []; | |||
| if (obj == null) return results; | |||
| if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); | |||
| each(obj, function(value, index, list) { | |||
| if (iterator.call(context, value, index, list)) results[results.length] = value; | |||
| }); | |||
| return results; | |||
| }; | |||
| // Return all the elements for which a truth test fails. | |||
| _.reject = function(obj, iterator, context) { | |||
| var results = []; | |||
| if (obj == null) return results; | |||
| each(obj, function(value, index, list) { | |||
| if (!iterator.call(context, value, index, list)) results[results.length] = value; | |||
| }); | |||
| return results; | |||
| }; | |||
| // Determine whether all of the elements match a truth test. | |||
| // Delegates to **ECMAScript 5**'s native `every` if available. | |||
| // Aliased as `all`. | |||
| _.every = _.all = function(obj, iterator, context) { | |||
| var result = true; | |||
| if (obj == null) return result; | |||
| if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); | |||
| each(obj, function(value, index, list) { | |||
| if (!(result = result && iterator.call(context, value, index, list))) return breaker; | |||
| }); | |||
| return result; | |||
| }; | |||
| // Determine if at least one element in the object matches a truth test. | |||
| // Delegates to **ECMAScript 5**'s native `some` if available. | |||
| // Aliased as `any`. | |||
| var any = _.some = _.any = function(obj, iterator, context) { | |||
| iterator || (iterator = _.identity); | |||
| var result = false; | |||
| if (obj == null) return result; | |||
| if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); | |||
| each(obj, function(value, index, list) { | |||
| if (result || (result = iterator.call(context, value, index, list))) return breaker; | |||
| }); | |||
| return !!result; | |||
| }; | |||
| // Determine if a given value is included in the array or object using `===`. | |||
| // Aliased as `contains`. | |||
| _.include = _.contains = function(obj, target) { | |||
| var found = false; | |||
| if (obj == null) return found; | |||
| if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; | |||
| found = any(obj, function(value) { | |||
| return value === target; | |||
| }); | |||
| return found; | |||
| }; | |||
| // Invoke a method (with arguments) on every item in a collection. | |||
| _.invoke = function(obj, method) { | |||
| var args = slice.call(arguments, 2); | |||
| return _.map(obj, function(value) { | |||
| return (_.isFunction(method) ? method || value : value[method]).apply(value, args); | |||
| }); | |||
| }; | |||
| // Convenience version of a common use case of `map`: fetching a property. | |||
| _.pluck = function(obj, key) { | |||
| return _.map(obj, function(value){ return value[key]; }); | |||
| }; | |||
| // Return the maximum element or (element-based computation). | |||
| _.max = function(obj, iterator, context) { | |||
| if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); | |||
| if (!iterator && _.isEmpty(obj)) return -Infinity; | |||
| var result = {computed : -Infinity}; | |||
| each(obj, function(value, index, list) { | |||
| var computed = iterator ? iterator.call(context, value, index, list) : value; | |||
| computed >= result.computed && (result = {value : value, computed : computed}); | |||
| }); | |||
| return result.value; | |||
| }; | |||
| // Return the minimum element (or element-based computation). | |||
| _.min = function(obj, iterator, context) { | |||
| if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); | |||
| if (!iterator && _.isEmpty(obj)) return Infinity; | |||
| var result = {computed : Infinity}; | |||
| each(obj, function(value, index, list) { | |||
| var computed = iterator ? iterator.call(context, value, index, list) : value; | |||
| computed < result.computed && (result = {value : value, computed : computed}); | |||
| }); | |||
| return result.value; | |||
| }; | |||
| // Shuffle an array. | |||
| _.shuffle = function(obj) { | |||
| var shuffled = [], rand; | |||
| each(obj, function(value, index, list) { | |||
| if (index == 0) { | |||
| shuffled[0] = value; | |||
| } else { | |||
| rand = Math.floor(Math.random() * (index + 1)); | |||
| shuffled[index] = shuffled[rand]; | |||
| shuffled[rand] = value; | |||
| } | |||
| }); | |||
| return shuffled; | |||
| }; | |||
| // Sort the object's values by a criterion produced by an iterator. | |||
| _.sortBy = function(obj, iterator, context) { | |||
| return _.pluck(_.map(obj, function(value, index, list) { | |||
| return { | |||
| value : value, | |||
| criteria : iterator.call(context, value, index, list) | |||
| }; | |||
| }).sort(function(left, right) { | |||
| var a = left.criteria, b = right.criteria; | |||
| return a < b ? -1 : a > b ? 1 : 0; | |||
| }), 'value'); | |||
| }; | |||
| // Groups the object's values by a criterion. Pass either a string attribute | |||
| // to group by, or a function that returns the criterion. | |||
| _.groupBy = function(obj, val) { | |||
| var result = {}; | |||
| var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; | |||
| each(obj, function(value, index) { | |||
| var key = iterator(value, index); | |||
| (result[key] || (result[key] = [])).push(value); | |||
| }); | |||
| return result; | |||
| }; | |||
| // Use a comparator function to figure out at what index an object should | |||
| // be inserted so as to maintain order. Uses binary search. | |||
| _.sortedIndex = function(array, obj, iterator) { | |||
| iterator || (iterator = _.identity); | |||
| var low = 0, high = array.length; | |||
| while (low < high) { | |||
| var mid = (low + high) >> 1; | |||
| iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; | |||
| } | |||
| return low; | |||
| }; | |||
| // Safely convert anything iterable into a real, live array. | |||
| _.toArray = function(iterable) { | |||
| if (!iterable) return []; | |||
| if (iterable.toArray) return iterable.toArray(); | |||
| if (_.isArray(iterable)) return slice.call(iterable); | |||
| if (_.isArguments(iterable)) return slice.call(iterable); | |||
| return _.values(iterable); | |||
| }; | |||
| // Return the number of elements in an object. | |||
| _.size = function(obj) { | |||
| return _.toArray(obj).length; | |||
| }; | |||
| // Array Functions | |||
| // --------------- | |||
| // Get the first element of an array. Passing **n** will return the first N | |||
| // values in the array. Aliased as `head`. The **guard** check allows it to work | |||
| // with `_.map`. | |||
| _.first = _.head = function(array, n, guard) { | |||
| return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; | |||
| }; | |||
| // Returns everything but the last entry of the array. Especcialy useful on | |||
| // the arguments object. Passing **n** will return all the values in | |||
| // the array, excluding the last N. The **guard** check allows it to work with | |||
| // `_.map`. | |||
| _.initial = function(array, n, guard) { | |||
| return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); | |||
| }; | |||
| // Get the last element of an array. Passing **n** will return the last N | |||
| // values in the array. The **guard** check allows it to work with `_.map`. | |||
| _.last = function(array, n, guard) { | |||
| if ((n != null) && !guard) { | |||
| return slice.call(array, Math.max(array.length - n, 0)); | |||
| } else { | |||
| return array[array.length - 1]; | |||
| } | |||
| }; | |||
| // Returns everything but the first entry of the array. Aliased as `tail`. | |||
| // Especially useful on the arguments object. Passing an **index** will return | |||
| // the rest of the values in the array from that index onward. The **guard** | |||
| // check allows it to work with `_.map`. | |||
| _.rest = _.tail = function(array, index, guard) { | |||
| return slice.call(array, (index == null) || guard ? 1 : index); | |||
| }; | |||
| // Trim out all falsy values from an array. | |||
| _.compact = function(array) { | |||
| return _.filter(array, function(value){ return !!value; }); | |||
| }; | |||
| // Return a completely flattened version of an array. | |||
| _.flatten = function(array, shallow) { | |||
| return _.reduce(array, function(memo, value) { | |||
| if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); | |||
| memo[memo.length] = value; | |||
| return memo; | |||
| }, []); | |||
| }; | |||
| // Return a version of the array that does not contain the specified value(s). | |||
| _.without = function(array) { | |||
| return _.difference(array, slice.call(arguments, 1)); | |||
| }; | |||
| // Produce a duplicate-free version of the array. If the array has already | |||
| // been sorted, you have the option of using a faster algorithm. | |||
| // Aliased as `unique`. | |||
| _.uniq = _.unique = function(array, isSorted, iterator) { | |||
| var initial = iterator ? _.map(array, iterator) : array; | |||
| var result = []; | |||
| _.reduce(initial, function(memo, el, i) { | |||
| if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { | |||
| memo[memo.length] = el; | |||
| result[result.length] = array[i]; | |||
| } | |||
| return memo; | |||
| }, []); | |||
| return result; | |||
| }; | |||
| // Produce an array that contains the union: each distinct element from all of | |||
| // the passed-in arrays. | |||
| _.union = function() { | |||
| return _.uniq(_.flatten(arguments, true)); | |||
| }; | |||
| // Produce an array that contains every item shared between all the | |||
| // passed-in arrays. (Aliased as "intersect" for back-compat.) | |||
| _.intersection = _.intersect = function(array) { | |||
| var rest = slice.call(arguments, 1); | |||
| return _.filter(_.uniq(array), function(item) { | |||
| return _.every(rest, function(other) { | |||
| return _.indexOf(other, item) >= 0; | |||
| }); | |||
| }); | |||
| }; | |||
| // Take the difference between one array and a number of other arrays. | |||
| // Only the elements present in just the first array will remain. | |||
| _.difference = function(array) { | |||
| var rest = _.flatten(slice.call(arguments, 1)); | |||
| return _.filter(array, function(value){ return !_.include(rest, value); }); | |||
| }; | |||
| // Zip together multiple lists into a single array -- elements that share | |||
| // an index go together. | |||
| _.zip = function() { | |||
| var args = slice.call(arguments); | |||
| var length = _.max(_.pluck(args, 'length')); | |||
| var results = new Array(length); | |||
| for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); | |||
| return results; | |||
| }; | |||
| // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), | |||
| // we need this function. Return the position of the first occurrence of an | |||
| // item in an array, or -1 if the item is not included in the array. | |||
| // Delegates to **ECMAScript 5**'s native `indexOf` if available. | |||
| // If the array is large and already in sort order, pass `true` | |||
| // for **isSorted** to use binary search. | |||
| _.indexOf = function(array, item, isSorted) { | |||
| if (array == null) return -1; | |||
| var i, l; | |||
| if (isSorted) { | |||
| i = _.sortedIndex(array, item); | |||
| return array[i] === item ? i : -1; | |||
| } | |||
| if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); | |||
| for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; | |||
| return -1; | |||
| }; | |||
| // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. | |||
| _.lastIndexOf = function(array, item) { | |||
| if (array == null) return -1; | |||
| if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); | |||
| var i = array.length; | |||
| while (i--) if (i in array && array[i] === item) return i; | |||
| return -1; | |||
| }; | |||
| // Generate an integer Array containing an arithmetic progression. A port of | |||
| // the native Python `range()` function. See | |||
| // [the Python documentation](http://docs.python.org/library/functions.html#range). | |||
| _.range = function(start, stop, step) { | |||
| if (arguments.length <= 1) { | |||
| stop = start || 0; | |||
| start = 0; | |||
| } | |||
| step = arguments[2] || 1; | |||
| var len = Math.max(Math.ceil((stop - start) / step), 0); | |||
| var idx = 0; | |||
| var range = new Array(len); | |||
| while(idx < len) { | |||
| range[idx++] = start; | |||
| start += step; | |||
| } | |||
| return range; | |||
| }; | |||
| // Function (ahem) Functions | |||
| // ------------------ | |||
| // Reusable constructor function for prototype setting. | |||
| var ctor = function(){}; | |||
| // Create a function bound to a given object (assigning `this`, and arguments, | |||
| // optionally). Binding with arguments is also known as `curry`. | |||
| // Delegates to **ECMAScript 5**'s native `Function.bind` if available. | |||
| // We check for `func.bind` first, to fail fast when `func` is undefined. | |||
| _.bind = function bind(func, context) { | |||
| var bound, args; | |||
| if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); | |||
| if (!_.isFunction(func)) throw new TypeError; | |||
| args = slice.call(arguments, 2); | |||
| return bound = function() { | |||
| if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); | |||
| ctor.prototype = func.prototype; | |||
| var self = new ctor; | |||
| var result = func.apply(self, args.concat(slice.call(arguments))); | |||
| if (Object(result) === result) return result; | |||
| return self; | |||
| }; | |||
| }; | |||
| // Bind all of an object's methods to that object. Useful for ensuring that | |||
| // all callbacks defined on an object belong to it. | |||
| _.bindAll = function(obj) { | |||
| var funcs = slice.call(arguments, 1); | |||
| if (funcs.length == 0) funcs = _.functions(obj); | |||
| each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); | |||
| return obj; | |||
| }; | |||
| // Memoize an expensive function by storing its results. | |||
| _.memoize = function(func, hasher) { | |||
| var memo = {}; | |||
| hasher || (hasher = _.identity); | |||
| return function() { | |||
| var key = hasher.apply(this, arguments); | |||
| return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); | |||
| }; | |||
| }; | |||
| // Delays a function for the given number of milliseconds, and then calls | |||
| // it with the arguments supplied. | |||
| _.delay = function(func, wait) { | |||
| var args = slice.call(arguments, 2); | |||
| return setTimeout(function(){ return func.apply(func, args); }, wait); | |||
| }; | |||
| // Defers a function, scheduling it to run after the current call stack has | |||
| // cleared. | |||
| _.defer = function(func) { | |||
| return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); | |||
| }; | |||
| // Returns a function, that, when invoked, will only be triggered at most once | |||
| // during a given window of time. | |||
| _.throttle = function(func, wait) { | |||
| var context, args, timeout, throttling, more; | |||
| var whenDone = _.debounce(function(){ more = throttling = false; }, wait); | |||
| return function() { | |||
| context = this; args = arguments; | |||
| var later = function() { | |||
| timeout = null; | |||
| if (more) func.apply(context, args); | |||
| whenDone(); | |||
| }; | |||
| if (!timeout) timeout = setTimeout(later, wait); | |||
| if (throttling) { | |||
| more = true; | |||
| } else { | |||
| func.apply(context, args); | |||
| } | |||
| whenDone(); | |||
| throttling = true; | |||
| }; | |||
| }; | |||
| // Returns a function, that, as long as it continues to be invoked, will not | |||
| // be triggered. The function will be called after it stops being called for | |||
| // N milliseconds. | |||
| _.debounce = function(func, wait) { | |||
| var timeout; | |||
| return function() { | |||
| var context = this, args = arguments; | |||
| var later = function() { | |||
| timeout = null; | |||
| func.apply(context, args); | |||
| }; | |||
| clearTimeout(timeout); | |||
| timeout = setTimeout(later, wait); | |||
| }; | |||
| }; | |||
| // Returns a function that will be executed at most one time, no matter how | |||
| // often you call it. Useful for lazy initialization. | |||
| _.once = function(func) { | |||
| var ran = false, memo; | |||
| return function() { | |||
| if (ran) return memo; | |||
| ran = true; | |||
| return memo = func.apply(this, arguments); | |||
| }; | |||
| }; | |||
| // Returns the first function passed as an argument to the second, | |||
| // allowing you to adjust arguments, run code before and after, and | |||
| // conditionally execute the original function. | |||
| _.wrap = function(func, wrapper) { | |||
| return function() { | |||
| var args = [func].concat(slice.call(arguments, 0)); | |||
| return wrapper.apply(this, args); | |||
| }; | |||
| }; | |||
| // Returns a function that is the composition of a list of functions, each | |||
| // consuming the return value of the function that follows. | |||
| _.compose = function() { | |||
| var funcs = arguments; | |||
| return function() { | |||
| var args = arguments; | |||
| for (var i = funcs.length - 1; i >= 0; i--) { | |||
| args = [funcs[i].apply(this, args)]; | |||
| } | |||
| return args[0]; | |||
| }; | |||
| }; | |||
| // Returns a function that will only be executed after being called N times. | |||
| _.after = function(times, func) { | |||
| if (times <= 0) return func(); | |||
| return function() { | |||
| if (--times < 1) { return func.apply(this, arguments); } | |||
| }; | |||
| }; | |||
| // Object Functions | |||
| // ---------------- | |||
| // Retrieve the names of an object's properties. | |||
| // Delegates to **ECMAScript 5**'s native `Object.keys` | |||
| _.keys = nativeKeys || function(obj) { | |||
| if (obj !== Object(obj)) throw new TypeError('Invalid object'); | |||
| var keys = []; | |||
| for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; | |||
| return keys; | |||
| }; | |||
| // Retrieve the values of an object's properties. | |||
| _.values = function(obj) { | |||
| return _.map(obj, _.identity); | |||
| }; | |||
| // Return a sorted list of the function names available on the object. | |||
| // Aliased as `methods` | |||
| _.functions = _.methods = function(obj) { | |||
| var names = []; | |||
| for (var key in obj) { | |||
| if (_.isFunction(obj[key])) names.push(key); | |||
| } | |||
| return names.sort(); | |||
| }; | |||
| // Extend a given object with all the properties in passed-in object(s). | |||
| _.extend = function(obj) { | |||
| each(slice.call(arguments, 1), function(source) { | |||
| for (var prop in source) { | |||
| obj[prop] = source[prop]; | |||
| } | |||
| }); | |||
| return obj; | |||
| }; | |||
| // Fill in a given object with default properties. | |||
| _.defaults = function(obj) { | |||
| each(slice.call(arguments, 1), function(source) { | |||
| for (var prop in source) { | |||
| if (obj[prop] == null) obj[prop] = source[prop]; | |||
| } | |||
| }); | |||
| return obj; | |||
| }; | |||
| // Create a (shallow-cloned) duplicate of an object. | |||
| _.clone = function(obj) { | |||
| if (!_.isObject(obj)) return obj; | |||
| return _.isArray(obj) ? obj.slice() : _.extend({}, obj); | |||
| }; | |||
| // Invokes interceptor with the obj, and then returns obj. | |||
| // The primary purpose of this method is to "tap into" a method chain, in | |||
| // order to perform operations on intermediate results within the chain. | |||
| _.tap = function(obj, interceptor) { | |||
| interceptor(obj); | |||
| return obj; | |||
| }; | |||
| // Internal recursive comparison function. | |||
| function eq(a, b, stack) { | |||
| // Identical objects are equal. `0 === -0`, but they aren't identical. | |||
| // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. | |||
| if (a === b) return a !== 0 || 1 / a == 1 / b; | |||
| // A strict comparison is necessary because `null == undefined`. | |||
| if (a == null || b == null) return a === b; | |||
| // Unwrap any wrapped objects. | |||
| if (a._chain) a = a._wrapped; | |||
| if (b._chain) b = b._wrapped; | |||
| // Invoke a custom `isEqual` method if one is provided. | |||
| if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); | |||
| if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); | |||
| // Compare `[[Class]]` names. | |||
| var className = toString.call(a); | |||
| if (className != toString.call(b)) return false; | |||
| switch (className) { | |||
| // Strings, numbers, dates, and booleans are compared by value. | |||
| case '[object String]': | |||
| // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is | |||
| // equivalent to `new String("5")`. | |||
| return a == String(b); | |||
| case '[object Number]': | |||
| // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for | |||
| // other numeric values. | |||
| return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); | |||
| case '[object Date]': | |||
| case '[object Boolean]': | |||
| // Coerce dates and booleans to numeric primitive values. Dates are compared by their | |||
| // millisecond representations. Note that invalid dates with millisecond representations | |||
| // of `NaN` are not equivalent. | |||
| return +a == +b; | |||
| // RegExps are compared by their source patterns and flags. | |||
| case '[object RegExp]': | |||
| return a.source == b.source && | |||
| a.global == b.global && | |||
| a.multiline == b.multiline && | |||
| a.ignoreCase == b.ignoreCase; | |||
| } | |||
| if (typeof a != 'object' || typeof b != 'object') return false; | |||
| // Assume equality for cyclic structures. The algorithm for detecting cyclic | |||
| // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. | |||
| var length = stack.length; | |||
| while (length--) { | |||
| // Linear search. Performance is inversely proportional to the number of | |||
| // unique nested structures. | |||
| if (stack[length] == a) return true; | |||
| } | |||
| // Add the first object to the stack of traversed objects. | |||
| stack.push(a); | |||
| var size = 0, result = true; | |||
| // Recursively compare objects and arrays. | |||
| if (className == '[object Array]') { | |||
| // Compare array lengths to determine if a deep comparison is necessary. | |||
| size = a.length; | |||
| result = size == b.length; | |||
| if (result) { | |||
| // Deep compare the contents, ignoring non-numeric properties. | |||
| while (size--) { | |||
| // Ensure commutative equality for sparse arrays. | |||
| if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; | |||
| } | |||
| } | |||
| } else { | |||
| // Objects with different constructors are not equivalent. | |||
| if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; | |||
| // Deep compare objects. | |||
| for (var key in a) { | |||
| if (_.has(a, key)) { | |||
| // Count the expected number of properties. | |||
| size++; | |||
| // Deep compare each member. | |||
| if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; | |||
| } | |||
| } | |||
| // Ensure that both objects contain the same number of properties. | |||
| if (result) { | |||
| for (key in b) { | |||
| if (_.has(b, key) && !(size--)) break; | |||
| } | |||
| result = !size; | |||
| } | |||
| } | |||
| // Remove the first object from the stack of traversed objects. | |||
| stack.pop(); | |||
| return result; | |||
| } | |||
| // Perform a deep comparison to check if two objects are equal. | |||
| _.isEqual = function(a, b) { | |||
| return eq(a, b, []); | |||
| }; | |||
| // Is a given array, string, or object empty? | |||
| // An "empty" object has no enumerable own-properties. | |||
| _.isEmpty = function(obj) { | |||
| if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; | |||
| for (var key in obj) if (_.has(obj, key)) return false; | |||
| return true; | |||
| }; | |||
| // Is a given value a DOM element? | |||
| _.isElement = function(obj) { | |||
| return !!(obj && obj.nodeType == 1); | |||
| }; | |||
| // Is a given value an array? | |||
| // Delegates to ECMA5's native Array.isArray | |||
| _.isArray = nativeIsArray || function(obj) { | |||
| return toString.call(obj) == '[object Array]'; | |||
| }; | |||
| // Is a given variable an object? | |||
| _.isObject = function(obj) { | |||
| return obj === Object(obj); | |||
| }; | |||
| // Is a given variable an arguments object? | |||
| _.isArguments = function(obj) { | |||
| return toString.call(obj) == '[object Arguments]'; | |||
| }; | |||
| if (!_.isArguments(arguments)) { | |||
| _.isArguments = function(obj) { | |||
| return !!(obj && _.has(obj, 'callee')); | |||
| }; | |||
| } | |||
| // Is a given value a function? | |||
| _.isFunction = function(obj) { | |||
| return toString.call(obj) == '[object Function]'; | |||
| }; | |||
| // Is a given value a string? | |||
| _.isString = function(obj) { | |||
| return toString.call(obj) == '[object String]'; | |||
| }; | |||
| // Is a given value a number? | |||
| _.isNumber = function(obj) { | |||
| return toString.call(obj) == '[object Number]'; | |||
| }; | |||
| // Is the given value `NaN`? | |||
| _.isNaN = function(obj) { | |||
| // `NaN` is the only value for which `===` is not reflexive. | |||
| return obj !== obj; | |||
| }; | |||
| // Is a given value a boolean? | |||
| _.isBoolean = function(obj) { | |||
| return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; | |||
| }; | |||
| // Is a given value a date? | |||
| _.isDate = function(obj) { | |||
| return toString.call(obj) == '[object Date]'; | |||
| }; | |||
| // Is the given value a regular expression? | |||
| _.isRegExp = function(obj) { | |||
| return toString.call(obj) == '[object RegExp]'; | |||
| }; | |||
| // Is a given value equal to null? | |||
| _.isNull = function(obj) { | |||
| return obj === null; | |||
| }; | |||
| // Is a given variable undefined? | |||
| _.isUndefined = function(obj) { | |||
| return obj === void 0; | |||
| }; | |||
| // Has own property? | |||
| _.has = function(obj, key) { | |||
| return hasOwnProperty.call(obj, key); | |||
| }; | |||
| // Utility Functions | |||
| // ----------------- | |||
| // Run Underscore.js in *noConflict* mode, returning the `_` variable to its | |||
| // previous owner. Returns a reference to the Underscore object. | |||
| _.noConflict = function() { | |||
| root._ = previousUnderscore; | |||
| return this; | |||
| }; | |||
| // Keep the identity function around for default iterators. | |||
| _.identity = function(value) { | |||
| return value; | |||
| }; | |||
| // Run a function **n** times. | |||
| _.times = function (n, iterator, context) { | |||
| for (var i = 0; i < n; i++) iterator.call(context, i); | |||
| }; | |||
| // Escape a string for HTML interpolation. | |||
| _.escape = function(string) { | |||
| return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); | |||
| }; | |||
| // Add your own custom functions to the Underscore object, ensuring that | |||
| // they're correctly added to the OOP wrapper as well. | |||
| _.mixin = function(obj) { | |||
| each(_.functions(obj), function(name){ | |||
| addToWrapper(name, _[name] = obj[name]); | |||
| }); | |||
| }; | |||
| // Generate a unique integer id (unique within the entire client session). | |||
| // Useful for temporary DOM ids. | |||
| var idCounter = 0; | |||
| _.uniqueId = function(prefix) { | |||
| var id = idCounter++; | |||
| return prefix ? prefix + id : id; | |||
| }; | |||
| // By default, Underscore uses ERB-style template delimiters, change the | |||
| // following template settings to use alternative delimiters. | |||
| _.templateSettings = { | |||
| evaluate : /<%([\s\S]+?)%>/g, | |||
| interpolate : /<%=([\s\S]+?)%>/g, | |||
| escape : /<%-([\s\S]+?)%>/g | |||
| }; | |||
| // When customizing `templateSettings`, if you don't want to define an | |||
| // interpolation, evaluation or escaping regex, we need one that is | |||
| // guaranteed not to match. | |||
| var noMatch = /.^/; | |||
| // Within an interpolation, evaluation, or escaping, remove HTML escaping | |||
| // that had been previously added. | |||
| var unescape = function(code) { | |||
| return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'"); | |||
| }; | |||
| // JavaScript micro-templating, similar to John Resig's implementation. | |||
| // Underscore templating handles arbitrary delimiters, preserves whitespace, | |||
| // and correctly escapes quotes within interpolated code. | |||
| _.template = function(str, data) { | |||
| var c = _.templateSettings; | |||
| var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + | |||
| 'with(obj||{}){__p.push(\'' + | |||
| str.replace(/\\/g, '\\\\') | |||
| .replace(/'/g, "\\'") | |||
| .replace(c.escape || noMatch, function(match, code) { | |||
| return "',_.escape(" + unescape(code) + "),'"; | |||
| }) | |||
| .replace(c.interpolate || noMatch, function(match, code) { | |||
| return "'," + unescape(code) + ",'"; | |||
| }) | |||
| .replace(c.evaluate || noMatch, function(match, code) { | |||
| return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('"; | |||
| }) | |||
| .replace(/\r/g, '\\r') | |||
| .replace(/\n/g, '\\n') | |||
| .replace(/\t/g, '\\t') | |||
| + "');}return __p.join('');"; | |||
| var func = new Function('obj', '_', tmpl); | |||
| if (data) return func(data, _); | |||
| return function(data) { | |||
| return func.call(this, data, _); | |||
| }; | |||
| }; | |||
| // Add a "chain" function, which will delegate to the wrapper. | |||
| _.chain = function(obj) { | |||
| return _(obj).chain(); | |||
| }; | |||
| // The OOP Wrapper | |||
| // --------------- | |||
| // If Underscore is called as a function, it returns a wrapped object that | |||
| // can be used OO-style. This wrapper holds altered versions of all the | |||
| // underscore functions. Wrapped objects may be chained. | |||
| var wrapper = function(obj) { this._wrapped = obj; }; | |||
| // Expose `wrapper.prototype` as `_.prototype` | |||
| _.prototype = wrapper.prototype; | |||
| // Helper function to continue chaining intermediate results. | |||
| var result = function(obj, chain) { | |||
| return chain ? _(obj).chain() : obj; | |||
| }; | |||
| // A method to easily add functions to the OOP wrapper. | |||
| var addToWrapper = function(name, func) { | |||
| wrapper.prototype[name] = function() { | |||
| var args = slice.call(arguments); | |||
| unshift.call(args, this._wrapped); | |||
| return result(func.apply(_, args), this._chain); | |||
| }; | |||
| }; | |||
| // Add all of the Underscore functions to the wrapper object. | |||
| _.mixin(_); | |||
| // Add all mutator Array functions to the wrapper. | |||
| each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { | |||
| var method = ArrayProto[name]; | |||
| wrapper.prototype[name] = function() { | |||
| var wrapped = this._wrapped; | |||
| method.apply(wrapped, arguments); | |||
| var length = wrapped.length; | |||
| if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; | |||
| return result(wrapped, this._chain); | |||
| }; | |||
| }); | |||
| // Add all accessor Array functions to the wrapper. | |||
| each(['concat', 'join', 'slice'], function(name) { | |||
| var method = ArrayProto[name]; | |||
| wrapper.prototype[name] = function() { | |||
| return result(method.apply(this._wrapped, arguments), this._chain); | |||
| }; | |||
| }); | |||
| // Start chaining a wrapped Underscore object. | |||
| wrapper.prototype.chain = function() { | |||
| this._chain = true; | |||
| return this; | |||
| }; | |||
| // Extracts the result from a wrapped and chained object. | |||
| wrapper.prototype.value = function() { | |||
| return this._wrapped; | |||
| }; | |||
| }).call(this); | |||
| @ -0,0 +1,31 @@ | |||
| // Underscore.js 1.3.1 | |||
| // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. | |||
| // Underscore is freely distributable under the MIT license. | |||
| // Portions of Underscore are inspired or borrowed from Prototype, | |||
| // Oliver Steele's Functional, and John Resig's Micro-Templating. | |||
| // For all details and documentation: | |||
| // http://documentcloud.github.com/underscore | |||
| (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== | |||
| c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, | |||
| h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= | |||
| b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a== | |||
| null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= | |||
| function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= | |||
| e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= | |||
| function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})}); | |||
| return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, | |||
| c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest= | |||
| b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]); | |||
| return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c, | |||
| d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g}; | |||
| var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a, | |||
| c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true: | |||
| a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}}; | |||
| b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, | |||
| 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; | |||
| b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; | |||
| b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), | |||
| function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ | |||
| u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= | |||
| function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= | |||
| true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); | |||
| @ -0,0 +1,808 @@ | |||
| /* | |||
| * websupport.js | |||
| * ~~~~~~~~~~~~~ | |||
| * | |||
| * sphinx.websupport utilities for all documentation. | |||
| * | |||
| * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. | |||
| * :license: BSD, see LICENSE for details. | |||
| * | |||
| */ | |||
| (function($) { | |||
| $.fn.autogrow = function() { | |||
| return this.each(function() { | |||
| var textarea = this; | |||
| $.fn.autogrow.resize(textarea); | |||
| $(textarea) | |||
| .focus(function() { | |||
| textarea.interval = setInterval(function() { | |||
| $.fn.autogrow.resize(textarea); | |||
| }, 500); | |||
| }) | |||
| .blur(function() { | |||
| clearInterval(textarea.interval); | |||
| }); | |||
| }); | |||
| }; | |||
| $.fn.autogrow.resize = function(textarea) { | |||
| var lineHeight = parseInt($(textarea).css('line-height'), 10); | |||
| var lines = textarea.value.split('\n'); | |||
| var columns = textarea.cols; | |||
| var lineCount = 0; | |||
| $.each(lines, function() { | |||
| lineCount += Math.ceil(this.length / columns) || 1; | |||
| }); | |||
| var height = lineHeight * (lineCount + 1); | |||
| $(textarea).css('height', height); | |||
| }; | |||
| })(jQuery); | |||
| (function($) { | |||
| var comp, by; | |||
| function init() { | |||
| initEvents(); | |||
| initComparator(); | |||
| } | |||
| function initEvents() { | |||
| $(document).on("click", 'a.comment-close', function(event) { | |||
| event.preventDefault(); | |||
| hide($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.vote', function(event) { | |||
| event.preventDefault(); | |||
| handleVote($(this)); | |||
| }); | |||
| $(document).on("click", 'a.reply', function(event) { | |||
| event.preventDefault(); | |||
| openReply($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.close-reply', function(event) { | |||
| event.preventDefault(); | |||
| closeReply($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.sort-option', function(event) { | |||
| event.preventDefault(); | |||
| handleReSort($(this)); | |||
| }); | |||
| $(document).on("click", 'a.show-proposal', function(event) { | |||
| event.preventDefault(); | |||
| showProposal($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.hide-proposal', function(event) { | |||
| event.preventDefault(); | |||
| hideProposal($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.show-propose-change', function(event) { | |||
| event.preventDefault(); | |||
| showProposeChange($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.hide-propose-change', function(event) { | |||
| event.preventDefault(); | |||
| hideProposeChange($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.accept-comment', function(event) { | |||
| event.preventDefault(); | |||
| acceptComment($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.delete-comment', function(event) { | |||
| event.preventDefault(); | |||
| deleteComment($(this).attr('id').substring(2)); | |||
| }); | |||
| $(document).on("click", 'a.comment-markup', function(event) { | |||
| event.preventDefault(); | |||
| toggleCommentMarkupBox($(this).attr('id').substring(2)); | |||
| }); | |||
| } | |||
| /** | |||
| * Set comp, which is a comparator function used for sorting and | |||
| * inserting comments into the list. | |||
| */ | |||
| function setComparator() { | |||
| // If the first three letters are "asc", sort in ascending order | |||
| // and remove the prefix. | |||
| if (by.substring(0,3) == 'asc') { | |||
| var i = by.substring(3); | |||
| comp = function(a, b) { return a[i] - b[i]; }; | |||
| } else { | |||
| // Otherwise sort in descending order. | |||
| comp = function(a, b) { return b[by] - a[by]; }; | |||
| } | |||
| // Reset link styles and format the selected sort option. | |||
| $('a.sel').attr('href', '#').removeClass('sel'); | |||
| $('a.by' + by).removeAttr('href').addClass('sel'); | |||
| } | |||
| /** | |||
| * Create a comp function. If the user has preferences stored in | |||
| * the sortBy cookie, use those, otherwise use the default. | |||
| */ | |||
| function initComparator() { | |||
| by = 'rating'; // Default to sort by rating. | |||
| // If the sortBy cookie is set, use that instead. | |||
| if (document.cookie.length > 0) { | |||
| var start = document.cookie.indexOf('sortBy='); | |||
| if (start != -1) { | |||
| start = start + 7; | |||
| var end = document.cookie.indexOf(";", start); | |||
| if (end == -1) { | |||
| end = document.cookie.length; | |||
| by = unescape(document.cookie.substring(start, end)); | |||
| } | |||
| } | |||
| } | |||
| setComparator(); | |||
| } | |||
| /** | |||
| * Show a comment div. | |||
| */ | |||
| function show(id) { | |||
| $('#ao' + id).hide(); | |||
| $('#ah' + id).show(); | |||
| var context = $.extend({id: id}, opts); | |||
| var popup = $(renderTemplate(popupTemplate, context)).hide(); | |||
| popup.find('textarea[name="proposal"]').hide(); | |||
| popup.find('a.by' + by).addClass('sel'); | |||
| var form = popup.find('#cf' + id); | |||
| form.submit(function(event) { | |||
| event.preventDefault(); | |||
| addComment(form); | |||
| }); | |||
| $('#s' + id).after(popup); | |||
| popup.slideDown('fast', function() { | |||
| getComments(id); | |||
| }); | |||
| } | |||
| /** | |||
| * Hide a comment div. | |||
| */ | |||
| function hide(id) { | |||
| $('#ah' + id).hide(); | |||
| $('#ao' + id).show(); | |||
| var div = $('#sc' + id); | |||
| div.slideUp('fast', function() { | |||
| div.remove(); | |||
| }); | |||
| } | |||
| /** | |||
| * Perform an ajax request to get comments for a node | |||
| * and insert the comments into the comments tree. | |||
| */ | |||
| function getComments(id) { | |||
| $.ajax({ | |||
| type: 'GET', | |||
| url: opts.getCommentsURL, | |||
| data: {node: id}, | |||
| success: function(data, textStatus, request) { | |||
| var ul = $('#cl' + id); | |||
| var speed = 100; | |||
| $('#cf' + id) | |||
| .find('textarea[name="proposal"]') | |||
| .data('source', data.source); | |||
| if (data.comments.length === 0) { | |||
| ul.html('<li>No comments yet.</li>'); | |||
| ul.data('empty', true); | |||
| } else { | |||
| // If there are comments, sort them and put them in the list. | |||
| var comments = sortComments(data.comments); | |||
| speed = data.comments.length * 100; | |||
| appendComments(comments, ul); | |||
| ul.data('empty', false); | |||
| } | |||
| $('#cn' + id).slideUp(speed + 200); | |||
| ul.slideDown(speed); | |||
| }, | |||
| error: function(request, textStatus, error) { | |||
| showError('Oops, there was a problem retrieving the comments.'); | |||
| }, | |||
| dataType: 'json' | |||
| }); | |||
| } | |||
| /** | |||
| * Add a comment via ajax and insert the comment into the comment tree. | |||
| */ | |||
| function addComment(form) { | |||
| var node_id = form.find('input[name="node"]').val(); | |||
| var parent_id = form.find('input[name="parent"]').val(); | |||
| var text = form.find('textarea[name="comment"]').val(); | |||
| var proposal = form.find('textarea[name="proposal"]').val(); | |||
| if (text == '') { | |||
| showError('Please enter a comment.'); | |||
| return; | |||
| } | |||
| // Disable the form that is being submitted. | |||
| form.find('textarea,input').attr('disabled', 'disabled'); | |||
| // Send the comment to the server. | |||
| $.ajax({ | |||
| type: "POST", | |||
| url: opts.addCommentURL, | |||
| dataType: 'json', | |||
| data: { | |||
| node: node_id, | |||
| parent: parent_id, | |||
| text: text, | |||
| proposal: proposal | |||
| }, | |||
| success: function(data, textStatus, error) { | |||
| // Reset the form. | |||
| if (node_id) { | |||
| hideProposeChange(node_id); | |||
| } | |||
| form.find('textarea') | |||
| .val('') | |||
| .add(form.find('input')) | |||
| .removeAttr('disabled'); | |||
| var ul = $('#cl' + (node_id || parent_id)); | |||
| if (ul.data('empty')) { | |||
| $(ul).empty(); | |||
| ul.data('empty', false); | |||
| } | |||
| insertComment(data.comment); | |||
| var ao = $('#ao' + node_id); | |||
| ao.find('img').attr({'src': opts.commentBrightImage}); | |||
| if (node_id) { | |||
| // if this was a "root" comment, remove the commenting box | |||
| // (the user can get it back by reopening the comment popup) | |||
| $('#ca' + node_id).slideUp(); | |||
| } | |||
| }, | |||
| error: function(request, textStatus, error) { | |||
| form.find('textarea,input').removeAttr('disabled'); | |||
| showError('Oops, there was a problem adding the comment.'); | |||
| } | |||
| }); | |||
| } | |||
| /** | |||
| * Recursively append comments to the main comment list and children | |||
| * lists, creating the comment tree. | |||
| */ | |||
| function appendComments(comments, ul) { | |||
| $.each(comments, function() { | |||
| var div = createCommentDiv(this); | |||
| ul.append($(document.createElement('li')).html(div)); | |||
| appendComments(this.children, div.find('ul.comment-children')); | |||
| // To avoid stagnating data, don't store the comments children in data. | |||
| this.children = null; | |||
| div.data('comment', this); | |||
| }); | |||
| } | |||
| /** | |||
| * After adding a new comment, it must be inserted in the correct | |||
| * location in the comment tree. | |||
| */ | |||
| function insertComment(comment) { | |||
| var div = createCommentDiv(comment); | |||
| // To avoid stagnating data, don't store the comments children in data. | |||
| comment.children = null; | |||
| div.data('comment', comment); | |||
| var ul = $('#cl' + (comment.node || comment.parent)); | |||
| var siblings = getChildren(ul); | |||
| var li = $(document.createElement('li')); | |||
| li.hide(); | |||
| // Determine where in the parents children list to insert this comment. | |||
| for(var i=0; i < siblings.length; i++) { | |||
| if (comp(comment, siblings[i]) <= 0) { | |||
| $('#cd' + siblings[i].id) | |||
| .parent() | |||
| .before(li.html(div)); | |||
| li.slideDown('fast'); | |||
| return; | |||
| } | |||
| } | |||
| // If we get here, this comment rates lower than all the others, | |||
| // or it is the only comment in the list. | |||
| ul.append(li.html(div)); | |||
| li.slideDown('fast'); | |||
| } | |||
| function acceptComment(id) { | |||
| $.ajax({ | |||
| type: 'POST', | |||
| url: opts.acceptCommentURL, | |||
| data: {id: id}, | |||
| success: function(data, textStatus, request) { | |||
| $('#cm' + id).fadeOut('fast'); | |||
| $('#cd' + id).removeClass('moderate'); | |||
| }, | |||
| error: function(request, textStatus, error) { | |||
| showError('Oops, there was a problem accepting the comment.'); | |||
| } | |||
| }); | |||
| } | |||
| function deleteComment(id) { | |||
| $.ajax({ | |||
| type: 'POST', | |||
| url: opts.deleteCommentURL, | |||
| data: {id: id}, | |||
| success: function(data, textStatus, request) { | |||
| var div = $('#cd' + id); | |||
| if (data == 'delete') { | |||
| // Moderator mode: remove the comment and all children immediately | |||
| div.slideUp('fast', function() { | |||
| div.remove(); | |||
| }); | |||
| return; | |||
| } | |||
| // User mode: only mark the comment as deleted | |||
| div | |||
| .find('span.user-id:first') | |||
| .text('[deleted]').end() | |||
| .find('div.comment-text:first') | |||
| .text('[deleted]').end() | |||
| .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + | |||
| ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) | |||
| .remove(); | |||
| var comment = div.data('comment'); | |||
| comment.username = '[deleted]'; | |||
| comment.text = '[deleted]'; | |||
| div.data('comment', comment); | |||
| }, | |||
| error: function(request, textStatus, error) { | |||
| showError('Oops, there was a problem deleting the comment.'); | |||
| } | |||
| }); | |||
| } | |||
| function showProposal(id) { | |||
| $('#sp' + id).hide(); | |||
| $('#hp' + id).show(); | |||
| $('#pr' + id).slideDown('fast'); | |||
| } | |||
| function hideProposal(id) { | |||
| $('#hp' + id).hide(); | |||
| $('#sp' + id).show(); | |||
| $('#pr' + id).slideUp('fast'); | |||
| } | |||
| function showProposeChange(id) { | |||
| $('#pc' + id).hide(); | |||
| $('#hc' + id).show(); | |||
| var textarea = $('#pt' + id); | |||
| textarea.val(textarea.data('source')); | |||
| $.fn.autogrow.resize(textarea[0]); | |||
| textarea.slideDown('fast'); | |||
| } | |||
| function hideProposeChange(id) { | |||
| $('#hc' + id).hide(); | |||
| $('#pc' + id).show(); | |||
| var textarea = $('#pt' + id); | |||
| textarea.val('').removeAttr('disabled'); | |||
| textarea.slideUp('fast'); | |||
| } | |||
| function toggleCommentMarkupBox(id) { | |||
| $('#mb' + id).toggle(); | |||
| } | |||
| /** Handle when the user clicks on a sort by link. */ | |||
| function handleReSort(link) { | |||
| var classes = link.attr('class').split(/\s+/); | |||
| for (var i=0; i<classes.length; i++) { | |||
| if (classes[i] != 'sort-option') { | |||
| by = classes[i].substring(2); | |||
| } | |||
| } | |||
| setComparator(); | |||
| // Save/update the sortBy cookie. | |||
| var expiration = new Date(); | |||
| expiration.setDate(expiration.getDate() + 365); | |||
| document.cookie= 'sortBy=' + escape(by) + | |||
| ';expires=' + expiration.toUTCString(); | |||
| $('ul.comment-ul').each(function(index, ul) { | |||
| var comments = getChildren($(ul), true); | |||
| comments = sortComments(comments); | |||
| appendComments(comments, $(ul).empty()); | |||
| }); | |||
| } | |||
| /** | |||
| * Function to process a vote when a user clicks an arrow. | |||
| */ | |||
| function handleVote(link) { | |||
| if (!opts.voting) { | |||
| showError("You'll need to login to vote."); | |||
| return; | |||
| } | |||
| var id = link.attr('id'); | |||
| if (!id) { | |||
| // Didn't click on one of the voting arrows. | |||
| return; | |||
| } | |||
| // If it is an unvote, the new vote value is 0, | |||
| // Otherwise it's 1 for an upvote, or -1 for a downvote. | |||
| var value = 0; | |||
| if (id.charAt(1) != 'u') { | |||
| value = id.charAt(0) == 'u' ? 1 : -1; | |||
| } | |||
| // The data to be sent to the server. | |||
| var d = { | |||
| comment_id: id.substring(2), | |||
| value: value | |||
| }; | |||
| // Swap the vote and unvote links. | |||
| link.hide(); | |||
| $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id) | |||
| .show(); | |||
| // The div the comment is displayed in. | |||
| var div = $('div#cd' + d.comment_id); | |||
| var data = div.data('comment'); | |||
| // If this is not an unvote, and the other vote arrow has | |||
| // already been pressed, unpress it. | |||
| if ((d.value !== 0) && (data.vote === d.value * -1)) { | |||
| $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide(); | |||
| $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show(); | |||
| } | |||
| // Update the comments rating in the local data. | |||
| data.rating += (data.vote === 0) ? d.value : (d.value - data.vote); | |||
| data.vote = d.value; | |||
| div.data('comment', data); | |||
| // Change the rating text. | |||
| div.find('.rating:first') | |||
| .text(data.rating + ' point' + (data.rating == 1 ? '' : 's')); | |||
| // Send the vote information to the server. | |||
| $.ajax({ | |||
| type: "POST", | |||
| url: opts.processVoteURL, | |||
| data: d, | |||
| error: function(request, textStatus, error) { | |||
| showError('Oops, there was a problem casting that vote.'); | |||
| } | |||
| }); | |||
| } | |||
| /** | |||
| * Open a reply form used to reply to an existing comment. | |||
| */ | |||
| function openReply(id) { | |||
| // Swap out the reply link for the hide link | |||
| $('#rl' + id).hide(); | |||
| $('#cr' + id).show(); | |||
| // Add the reply li to the children ul. | |||
| var div = $(renderTemplate(replyTemplate, {id: id})).hide(); | |||
| $('#cl' + id) | |||
| .prepend(div) | |||
| // Setup the submit handler for the reply form. | |||
| .find('#rf' + id) | |||
| .submit(function(event) { | |||
| event.preventDefault(); | |||
| addComment($('#rf' + id)); | |||
| closeReply(id); | |||
| }) | |||
| .find('input[type=button]') | |||
| .click(function() { | |||
| closeReply(id); | |||
| }); | |||
| div.slideDown('fast', function() { | |||
| $('#rf' + id).find('textarea').focus(); | |||
| }); | |||
| } | |||
| /** | |||
| * Close the reply form opened with openReply. | |||
| */ | |||
| function closeReply(id) { | |||
| // Remove the reply div from the DOM. | |||
| $('#rd' + id).slideUp('fast', function() { | |||
| $(this).remove(); | |||
| }); | |||
| // Swap out the hide link for the reply link | |||
| $('#cr' + id).hide(); | |||
| $('#rl' + id).show(); | |||
| } | |||
| /** | |||
| * Recursively sort a tree of comments using the comp comparator. | |||
| */ | |||
| function sortComments(comments) { | |||
| comments.sort(comp); | |||
| $.each(comments, function() { | |||
| this.children = sortComments(this.children); | |||
| }); | |||
| return comments; | |||
| } | |||
| /** | |||
| * Get the children comments from a ul. If recursive is true, | |||
| * recursively include childrens' children. | |||
| */ | |||
| function getChildren(ul, recursive) { | |||
| var children = []; | |||
| ul.children().children("[id^='cd']") | |||
| .each(function() { | |||
| var comment = $(this).data('comment'); | |||
| if (recursive) | |||
| comment.children = getChildren($(this).find('#cl' + comment.id), true); | |||
| children.push(comment); | |||
| }); | |||
| return children; | |||
| } | |||
| /** Create a div to display a comment in. */ | |||
| function createCommentDiv(comment) { | |||
| if (!comment.displayed && !opts.moderator) { | |||
| return $('<div class="moderate">Thank you! Your comment will show up ' | |||
| + 'once it is has been approved by a moderator.</div>'); | |||
| } | |||
| // Prettify the comment rating. | |||
| comment.pretty_rating = comment.rating + ' point' + | |||
| (comment.rating == 1 ? '' : 's'); | |||
| // Make a class (for displaying not yet moderated comments differently) | |||
| comment.css_class = comment.displayed ? '' : ' moderate'; | |||
| // Create a div for this comment. | |||
| var context = $.extend({}, opts, comment); | |||
| var div = $(renderTemplate(commentTemplate, context)); | |||
| // If the user has voted on this comment, highlight the correct arrow. | |||
| if (comment.vote) { | |||
| var direction = (comment.vote == 1) ? 'u' : 'd'; | |||
| div.find('#' + direction + 'v' + comment.id).hide(); | |||
| div.find('#' + direction + 'u' + comment.id).show(); | |||
| } | |||
| if (opts.moderator || comment.text != '[deleted]') { | |||
| div.find('a.reply').show(); | |||
| if (comment.proposal_diff) | |||
| div.find('#sp' + comment.id).show(); | |||
| if (opts.moderator && !comment.displayed) | |||
| div.find('#cm' + comment.id).show(); | |||
| if (opts.moderator || (opts.username == comment.username)) | |||
| div.find('#dc' + comment.id).show(); | |||
| } | |||
| return div; | |||
| } | |||
| /** | |||
| * A simple template renderer. Placeholders such as <%id%> are replaced | |||
| * by context['id'] with items being escaped. Placeholders such as <#id#> | |||
| * are not escaped. | |||
| */ | |||
| function renderTemplate(template, context) { | |||
| var esc = $(document.createElement('div')); | |||
| function handle(ph, escape) { | |||
| var cur = context; | |||
| $.each(ph.split('.'), function() { | |||
| cur = cur[this]; | |||
| }); | |||
| return escape ? esc.text(cur || "").html() : cur; | |||
| } | |||
| return template.replace(/<([%#])([\w\.]*)\1>/g, function() { | |||
| return handle(arguments[2], arguments[1] == '%' ? true : false); | |||
| }); | |||
| } | |||
| /** Flash an error message briefly. */ | |||
| function showError(message) { | |||
| $(document.createElement('div')).attr({'class': 'popup-error'}) | |||
| .append($(document.createElement('div')) | |||
| .attr({'class': 'error-message'}).text(message)) | |||
| .appendTo('body') | |||
| .fadeIn("slow") | |||
| .delay(2000) | |||
| .fadeOut("slow"); | |||
| } | |||
| /** Add a link the user uses to open the comments popup. */ | |||
| $.fn.comment = function() { | |||
| return this.each(function() { | |||
| var id = $(this).attr('id').substring(1); | |||
| var count = COMMENT_METADATA[id]; | |||
| var title = count + ' comment' + (count == 1 ? '' : 's'); | |||
| var image = count > 0 ? opts.commentBrightImage : opts.commentImage; | |||
| var addcls = count == 0 ? ' nocomment' : ''; | |||
| $(this) | |||
| .append( | |||
| $(document.createElement('a')).attr({ | |||
| href: '#', | |||
| 'class': 'sphinx-comment-open' + addcls, | |||
| id: 'ao' + id | |||
| }) | |||
| .append($(document.createElement('img')).attr({ | |||
| src: image, | |||
| alt: 'comment', | |||
| title: title | |||
| })) | |||
| .click(function(event) { | |||
| event.preventDefault(); | |||
| show($(this).attr('id').substring(2)); | |||
| }) | |||
| ) | |||
| .append( | |||
| $(document.createElement('a')).attr({ | |||
| href: '#', | |||
| 'class': 'sphinx-comment-close hidden', | |||
| id: 'ah' + id | |||
| }) | |||
| .append($(document.createElement('img')).attr({ | |||
| src: opts.closeCommentImage, | |||
| alt: 'close', | |||
| title: 'close' | |||
| })) | |||
| .click(function(event) { | |||
| event.preventDefault(); | |||
| hide($(this).attr('id').substring(2)); | |||
| }) | |||
| ); | |||
| }); | |||
| }; | |||
| var opts = { | |||
| processVoteURL: '/_process_vote', | |||
| addCommentURL: '/_add_comment', | |||
| getCommentsURL: '/_get_comments', | |||
| acceptCommentURL: '/_accept_comment', | |||
| deleteCommentURL: '/_delete_comment', | |||
| commentImage: '/static/_static/comment.png', | |||
| closeCommentImage: '/static/_static/comment-close.png', | |||
| loadingImage: '/static/_static/ajax-loader.gif', | |||
| commentBrightImage: '/static/_static/comment-bright.png', | |||
| upArrow: '/static/_static/up.png', | |||
| downArrow: '/static/_static/down.png', | |||
| upArrowPressed: '/static/_static/up-pressed.png', | |||
| downArrowPressed: '/static/_static/down-pressed.png', | |||
| voting: false, | |||
| moderator: false | |||
| }; | |||
| if (typeof COMMENT_OPTIONS != "undefined") { | |||
| opts = jQuery.extend(opts, COMMENT_OPTIONS); | |||
| } | |||
| var popupTemplate = '\ | |||
| <div class="sphinx-comments" id="sc<%id%>">\ | |||
| <p class="sort-options">\ | |||
| Sort by:\ | |||
| <a href="#" class="sort-option byrating">best rated</a>\ | |||
| <a href="#" class="sort-option byascage">newest</a>\ | |||
| <a href="#" class="sort-option byage">oldest</a>\ | |||
| </p>\ | |||
| <div class="comment-header">Comments</div>\ | |||
| <div class="comment-loading" id="cn<%id%>">\ | |||
| loading comments... <img src="<%loadingImage%>" alt="" /></div>\ | |||
| <ul id="cl<%id%>" class="comment-ul"></ul>\ | |||
| <div id="ca<%id%>">\ | |||
| <p class="add-a-comment">Add a comment\ | |||
| (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\ | |||
| <div class="comment-markup-box" id="mb<%id%>">\ | |||
| reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \ | |||
| <code>``code``</code>, \ | |||
| code blocks: <code>::</code> and an indented block after blank line</div>\ | |||
| <form method="post" id="cf<%id%>" class="comment-form" action="">\ | |||
| <textarea name="comment" cols="80"></textarea>\ | |||
| <p class="propose-button">\ | |||
| <a href="#" id="pc<%id%>" class="show-propose-change">\ | |||
| Propose a change ▹\ | |||
| </a>\ | |||
| <a href="#" id="hc<%id%>" class="hide-propose-change">\ | |||
| Propose a change ▿\ | |||
| </a>\ | |||
| </p>\ | |||
| <textarea name="proposal" id="pt<%id%>" cols="80"\ | |||
| spellcheck="false"></textarea>\ | |||
| <input type="submit" value="Add comment" />\ | |||
| <input type="hidden" name="node" value="<%id%>" />\ | |||
| <input type="hidden" name="parent" value="" />\ | |||
| </form>\ | |||
| </div>\ | |||
| </div>'; | |||
| var commentTemplate = '\ | |||
| <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\ | |||
| <div class="vote">\ | |||
| <div class="arrow">\ | |||
| <a href="#" id="uv<%id%>" class="vote" title="vote up">\ | |||
| <img src="<%upArrow%>" />\ | |||
| </a>\ | |||
| <a href="#" id="uu<%id%>" class="un vote" title="vote up">\ | |||
| <img src="<%upArrowPressed%>" />\ | |||
| </a>\ | |||
| </div>\ | |||
| <div class="arrow">\ | |||
| <a href="#" id="dv<%id%>" class="vote" title="vote down">\ | |||
| <img src="<%downArrow%>" id="da<%id%>" />\ | |||
| </a>\ | |||
| <a href="#" id="du<%id%>" class="un vote" title="vote down">\ | |||
| <img src="<%downArrowPressed%>" />\ | |||
| </a>\ | |||
| </div>\ | |||
| </div>\ | |||
| <div class="comment-content">\ | |||
| <p class="tagline comment">\ | |||
| <span class="user-id"><%username%></span>\ | |||
| <span class="rating"><%pretty_rating%></span>\ | |||
| <span class="delta"><%time.delta%></span>\ | |||
| </p>\ | |||
| <div class="comment-text comment"><#text#></div>\ | |||
| <p class="comment-opts comment">\ | |||
| <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\ | |||
| <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\ | |||
| <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\ | |||
| <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\ | |||
| <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\ | |||
| <span id="cm<%id%>" class="moderation hidden">\ | |||
| <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\ | |||
| </span>\ | |||
| </p>\ | |||
| <pre class="proposal" id="pr<%id%>">\ | |||
| <#proposal_diff#>\ | |||
| </pre>\ | |||
| <ul class="comment-children" id="cl<%id%>"></ul>\ | |||
| </div>\ | |||
| <div class="clearleft"></div>\ | |||
| </div>\ | |||
| </div>'; | |||
| var replyTemplate = '\ | |||
| <li>\ | |||
| <div class="reply-div" id="rd<%id%>">\ | |||
| <form id="rf<%id%>">\ | |||
| <textarea name="comment" cols="80"></textarea>\ | |||
| <input type="submit" value="Add reply" />\ | |||
| <input type="button" value="Cancel" />\ | |||
| <input type="hidden" name="parent" value="<%id%>" />\ | |||
| <input type="hidden" name="node" value="" />\ | |||
| </form>\ | |||
| </div>\ | |||
| </li>'; | |||
| $(document).ready(function() { | |||
| init(); | |||
| }); | |||
| })(jQuery); | |||
| $(document).ready(function() { | |||
| // add comment anchors for all paragraphs that are commentable | |||
| $('.sphinx-has-comment').comment(); | |||
| // highlight search words in search results | |||
| $("div.context").each(function() { | |||
| var params = $.getQueryParameters(); | |||
| var terms = (params.q) ? params.q[0].split(/\s+/) : []; | |||
| var result = $(this); | |||
| $.each(terms, function() { | |||
| result.highlightText(this.toLowerCase(), 'highlighted'); | |||
| }); | |||
| }); | |||
| // directly open comment window if requested | |||
| var anchor = document.location.hash; | |||
| if (anchor.substring(0, 9) == '#comment-') { | |||
| $('#ao' + anchor.substring(9)).click(); | |||
| document.location.hash = '#s' + anchor.substring(9); | |||
| } | |||
| }); | |||
| @ -0,0 +1,145 @@ | |||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||
| <head> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> | |||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||
| <title>Index — importhook documentation</title> | |||
| <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> | |||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||
| <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> | |||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||
| <link rel="index" title="Index" href="#" /> | |||
| <link rel="search" title="Search" href="search.html" /> | |||
| <link rel="stylesheet" href="_static/custom.css" type="text/css" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> | |||
| </head><body> | |||
| <div class="document"> | |||
| <div class="documentwrapper"> | |||
| <div class="bodywrapper"> | |||
| <div class="body" role="main"> | |||
| <h1 id="index">Index</h1> | |||
| <div class="genindex-jumpbox"> | |||
| <a href="#C"><strong>C</strong></a> | |||
| | <a href="#G"><strong>G</strong></a> | |||
| | <a href="#I"><strong>I</strong></a> | |||
| | <a href="#O"><strong>O</strong></a> | |||
| | <a href="#R"><strong>R</strong></a> | |||
| </div> | |||
| <h2 id="C">C</h2> | |||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#importhook.copy_module">copy_module() (in module importhook)</a> | |||
| </li> | |||
| </ul></td> | |||
| </tr></table> | |||
| <h2 id="G">G</h2> | |||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#importhook.get_module_name">get_module_name() (in module importhook)</a> | |||
| </li> | |||
| </ul></td> | |||
| </tr></table> | |||
| <h2 id="I">I</h2> | |||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#module-importhook">importhook (module)</a> | |||
| </li> | |||
| </ul></td> | |||
| </tr></table> | |||
| <h2 id="O">O</h2> | |||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#importhook.on_import">on_import() (in module importhook)</a> | |||
| </li> | |||
| </ul></td> | |||
| </tr></table> | |||
| <h2 id="R">R</h2> | |||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#importhook.reload_module">reload_module() (in module importhook)</a> | |||
| </li> | |||
| </ul></td> | |||
| <td style="width: 33%; vertical-align: top;"><ul> | |||
| <li><a href="index.html#importhook.reset_module">reset_module() (in module importhook)</a> | |||
| </li> | |||
| </ul></td> | |||
| </tr></table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> | |||
| <div class="sphinxsidebarwrapper"> | |||
| <h1 class="logo"><a href="index.html">importhook</a></h1> | |||
| <h3>Navigation</h3> | |||
| <div class="relations"> | |||
| <h3>Related Topics</h3> | |||
| <ul> | |||
| <li><a href="index.html">Documentation overview</a><ul> | |||
| </ul></li> | |||
| </ul> | |||
| </div> | |||
| <div id="searchbox" style="display: none" role="search"> | |||
| <h3>Quick search</h3> | |||
| <div class="searchformwrapper"> | |||
| <form class="search" action="search.html" method="get"> | |||
| <input type="text" name="q" /> | |||
| <input type="submit" value="Go" /> | |||
| <input type="hidden" name="check_keywords" value="yes" /> | |||
| <input type="hidden" name="area" value="default" /> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||
| </div> | |||
| </div> | |||
| <div class="clearer"></div> | |||
| </div> | |||
| <div class="footer"> | |||
| ©2018, Brett Langdon <me@brett.is>. | |||
| | | |||
| Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.7</a> | |||
| & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.11</a> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,187 @@ | |||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||
| <head> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> | |||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||
| <title>importhook — importhook documentation</title> | |||
| <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> | |||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||
| <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> | |||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||
| <link rel="index" title="Index" href="genindex.html" /> | |||
| <link rel="search" title="Search" href="search.html" /> | |||
| <link rel="stylesheet" href="_static/custom.css" type="text/css" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> | |||
| </head><body> | |||
| <div class="document"> | |||
| <div class="documentwrapper"> | |||
| <div class="bodywrapper"> | |||
| <div class="body" role="main"> | |||
| <div class="toctree-wrapper compound"> | |||
| </div> | |||
| <span class="target" id="module-importhook"></span><div class="section" id="importhook"> | |||
| <h1>importhook<a class="headerlink" href="#importhook" title="Permalink to this headline">¶</a></h1> | |||
| <p>Python module for registering hooks to call when certain modules are imported.</p> | |||
| <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">importhook</span> | |||
| <span class="c1"># Configure a function to call when `socket` is imported</span> | |||
| <span class="nd">@importhook</span><span class="o">.</span><span class="n">on_import</span><span class="p">(</span><span class="s1">'socket'</span><span class="p">)</span> | |||
| <span class="k">def</span> <span class="nf">socket_import</span><span class="p">(</span><span class="n">socket</span><span class="p">):</span> | |||
| <span class="nb">print</span><span class="p">(</span><span class="s1">'Socket module imported'</span><span class="p">)</span> | |||
| <span class="c1"># Import the `socket` module</span> | |||
| <span class="kn">import</span> <span class="nn">socket</span> | |||
| </pre></div> | |||
| </div> | |||
| <dl class="function"> | |||
| <dt id="importhook.copy_module"> | |||
| <code class="descclassname">importhook.</code><code class="descname">copy_module</code><span class="sig-paren">(</span><em>module</em>, <em>copy_attributes=True</em>, <em>copy_spec=True</em><span class="sig-paren">)</span><a class="headerlink" href="#importhook.copy_module" title="Permalink to this definition">¶</a></dt> | |||
| <dd><p>Helper function for copying a python module</p> | |||
| <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">importhook</span> | |||
| <span class="nd">@importhook</span><span class="o">.</span><span class="n">on_import</span><span class="p">(</span><span class="s1">'socket'</span><span class="p">)</span> | |||
| <span class="k">def</span> <span class="nf">on_socket_import</span><span class="p">(</span><span class="n">socket</span><span class="p">):</span> | |||
| <span class="n">new_socket</span> <span class="o">=</span> <span class="n">importhook</span><span class="o">.</span><span class="n">copy_module</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span> | |||
| <span class="nb">setattr</span><span class="p">(</span><span class="n">new_socket</span><span class="p">,</span> <span class="s1">'get_hostname'</span><span class="p">,</span> <span class="k">lambda</span><span class="p">:</span> <span class="s1">'hostname'</span><span class="p">)</span> | |||
| <span class="k">return</span> <span class="n">new_socket</span> | |||
| </pre></div> | |||
| </div> | |||
| </dd></dl> | |||
| <dl class="function"> | |||
| <dt id="importhook.get_module_name"> | |||
| <code class="descclassname">importhook.</code><code class="descname">get_module_name</code><span class="sig-paren">(</span><em>module</em><span class="sig-paren">)</span><a class="headerlink" href="#importhook.get_module_name" title="Permalink to this definition">¶</a></dt> | |||
| <dd><p>Helper function to get a module’s name</p> | |||
| </dd></dl> | |||
| <dl class="function"> | |||
| <dt id="importhook.on_import"> | |||
| <code class="descclassname">importhook.</code><code class="descname">on_import</code><span class="sig-paren">(</span><em>module_name</em>, <em>func=None</em><span class="sig-paren">)</span><a class="headerlink" href="#importhook.on_import" title="Permalink to this definition">¶</a></dt> | |||
| <dd><p>Helper function used to register a hook function for a given module</p> | |||
| <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">importhook</span> | |||
| <span class="nd">@importhook</span><span class="o">.</span><span class="n">on_import</span><span class="p">(</span><span class="s1">'socket'</span><span class="p">)</span> | |||
| <span class="k">def</span> <span class="nf">on_socket_import</span><span class="p">(</span><span class="n">socket</span><span class="p">):</span> | |||
| <span class="nb">print</span><span class="p">(</span><span class="s1">'socket imported'</span><span class="p">)</span> | |||
| <span class="nd">@importhook</span><span class="o">.</span><span class="n">on_import</span><span class="p">(</span><span class="n">importhook</span><span class="o">.</span><span class="n">ANY_MODULE</span><span class="p">)</span> | |||
| <span class="k">def</span> <span class="nf">on_any_import</span><span class="p">(</span><span class="n">module</span><span class="p">):</span> | |||
| <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s1">'</span><span class="si">{module.__spec__.name}</span><span class="s1"> imported'</span><span class="p">)</span> | |||
| <span class="k">def</span> <span class="nf">on_httplib_import</span><span class="p">(</span><span class="n">httplib</span><span class="p">):</span> | |||
| <span class="nb">print</span><span class="p">(</span><span class="s1">'httplib imported'</span><span class="p">)</span> | |||
| <span class="n">importhook</span><span class="o">.</span><span class="n">on_import</span><span class="p">(</span><span class="s1">'httplib'</span><span class="p">,</span> <span class="n">on_httplib_import</span><span class="p">)</span> | |||
| </pre></div> | |||
| </div> | |||
| </dd></dl> | |||
| <dl class="function"> | |||
| <dt id="importhook.reload_module"> | |||
| <code class="descclassname">importhook.</code><code class="descname">reload_module</code><span class="sig-paren">(</span><em>module_name</em><span class="sig-paren">)</span><a class="headerlink" href="#importhook.reload_module" title="Permalink to this definition">¶</a></dt> | |||
| <dd><p>Helper function to reload the specified module</p> | |||
| <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span> | |||
| <span class="kn">import</span> <span class="nn">importhook</span> | |||
| <span class="c1"># Reload the `socket` module by passing in module</span> | |||
| <span class="n">socket</span> <span class="o">=</span> <span class="n">importhook</span><span class="o">.</span><span class="n">reload_module</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span> | |||
| <span class="c1"># Reload the `socket` module by passing in the name</span> | |||
| <span class="n">socket</span> <span class="o">=</span> <span class="n">importhook</span><span class="o">.</span><span class="n">reload_module</span><span class="p">(</span><span class="s1">'socket'</span><span class="p">)</span> | |||
| </pre></div> | |||
| </div> | |||
| </dd></dl> | |||
| <dl class="function"> | |||
| <dt id="importhook.reset_module"> | |||
| <code class="descclassname">importhook.</code><code class="descname">reset_module</code><span class="sig-paren">(</span><em>module_name</em><span class="sig-paren">)</span><a class="headerlink" href="#importhook.reset_module" title="Permalink to this definition">¶</a></dt> | |||
| <dd><p>Helper function to reset a copied module.</p> | |||
| <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span> | |||
| <span class="kn">import</span> <span class="nn">importhook</span> | |||
| <span class="c1"># Copy `socket` module</span> | |||
| <span class="n">socket</span> <span class="o">=</span> <span class="n">importhook</span><span class="o">.</span><span class="n">copy_module</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span> | |||
| <span class="c1"># Reset copied `socket` module back to it's original version</span> | |||
| <span class="n">socket</span> <span class="o">=</span> <span class="n">importhook</span><span class="o">.</span><span class="n">reset_module</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span> | |||
| </pre></div> | |||
| </div> | |||
| </dd></dl> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> | |||
| <div class="sphinxsidebarwrapper"> | |||
| <h1 class="logo"><a href="#">importhook</a></h1> | |||
| <h3>Navigation</h3> | |||
| <div class="relations"> | |||
| <h3>Related Topics</h3> | |||
| <ul> | |||
| <li><a href="#">Documentation overview</a><ul> | |||
| </ul></li> | |||
| </ul> | |||
| </div> | |||
| <div id="searchbox" style="display: none" role="search"> | |||
| <h3>Quick search</h3> | |||
| <div class="searchformwrapper"> | |||
| <form class="search" action="search.html" method="get"> | |||
| <input type="text" name="q" /> | |||
| <input type="submit" value="Go" /> | |||
| <input type="hidden" name="check_keywords" value="yes" /> | |||
| <input type="hidden" name="area" value="default" /> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||
| </div> | |||
| </div> | |||
| <div class="clearer"></div> | |||
| </div> | |||
| <div class="footer"> | |||
| ©2018, Brett Langdon <me@brett.is>. | |||
| | | |||
| Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.7</a> | |||
| & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.11</a> | |||
| | | |||
| <a href="_sources/index.rst.txt" | |||
| rel="nofollow">Page source</a> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,113 @@ | |||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||
| <head> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> | |||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||
| <title>Python Module Index — importhook documentation</title> | |||
| <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> | |||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||
| <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> | |||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||
| <link rel="index" title="Index" href="genindex.html" /> | |||
| <link rel="search" title="Search" href="search.html" /> | |||
| <link rel="stylesheet" href="_static/custom.css" type="text/css" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> | |||
| <script type="text/javascript"> | |||
| DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true; | |||
| </script> | |||
| </head><body> | |||
| <div class="document"> | |||
| <div class="documentwrapper"> | |||
| <div class="bodywrapper"> | |||
| <div class="body" role="main"> | |||
| <h1>Python Module Index</h1> | |||
| <div class="modindex-jumpbox"> | |||
| <a href="#cap-i"><strong>i</strong></a> | |||
| </div> | |||
| <table class="indextable modindextable"> | |||
| <tr class="pcap"><td></td><td> </td><td></td></tr> | |||
| <tr class="cap" id="cap-i"><td></td><td> | |||
| <strong>i</strong></td><td></td></tr> | |||
| <tr> | |||
| <td></td> | |||
| <td> | |||
| <a href="index.html#module-importhook"><code class="xref">importhook</code></a></td><td> | |||
| <em></em></td></tr> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> | |||
| <div class="sphinxsidebarwrapper"> | |||
| <h1 class="logo"><a href="index.html">importhook</a></h1> | |||
| <h3>Navigation</h3> | |||
| <div class="relations"> | |||
| <h3>Related Topics</h3> | |||
| <ul> | |||
| <li><a href="index.html">Documentation overview</a><ul> | |||
| </ul></li> | |||
| </ul> | |||
| </div> | |||
| <div id="searchbox" style="display: none" role="search"> | |||
| <h3>Quick search</h3> | |||
| <div class="searchformwrapper"> | |||
| <form class="search" action="search.html" method="get"> | |||
| <input type="text" name="q" /> | |||
| <input type="submit" value="Go" /> | |||
| <input type="hidden" name="check_keywords" value="yes" /> | |||
| <input type="hidden" name="area" value="default" /> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||
| </div> | |||
| </div> | |||
| <div class="clearer"></div> | |||
| </div> | |||
| <div class="footer"> | |||
| ©2018, Brett Langdon <me@brett.is>. | |||
| | | |||
| Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.7</a> | |||
| & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.11</a> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,107 @@ | |||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||
| <head> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> | |||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||
| <title>Search — importhook documentation</title> | |||
| <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> | |||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||
| <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> | |||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||
| <script type="text/javascript" src="_static/searchtools.js"></script> | |||
| <link rel="index" title="Index" href="genindex.html" /> | |||
| <link rel="search" title="Search" href="#" /> | |||
| <script type="text/javascript"> | |||
| jQuery(function() { Search.loadIndex("searchindex.js"); }); | |||
| </script> | |||
| <script type="text/javascript" id="searchindexloader"></script> | |||
| <link rel="stylesheet" href="_static/custom.css" type="text/css" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> | |||
| </head><body> | |||
| <div class="document"> | |||
| <div class="documentwrapper"> | |||
| <div class="bodywrapper"> | |||
| <div class="body" role="main"> | |||
| <h1 id="search-documentation">Search</h1> | |||
| <div id="fallback" class="admonition warning"> | |||
| <script type="text/javascript">$('#fallback').hide();</script> | |||
| <p> | |||
| Please activate JavaScript to enable the search | |||
| functionality. | |||
| </p> | |||
| </div> | |||
| <p> | |||
| From here you can search these documents. Enter your search | |||
| words into the box below and click "search". Note that the search | |||
| function will automatically search for all of the words. Pages | |||
| containing fewer words won't appear in the result list. | |||
| </p> | |||
| <form action="" method="get"> | |||
| <input type="text" name="q" value="" /> | |||
| <input type="submit" value="search" /> | |||
| <span id="search-progress" style="padding-left: 10px"></span> | |||
| </form> | |||
| <div id="search-results"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> | |||
| <div class="sphinxsidebarwrapper"> | |||
| <h1 class="logo"><a href="index.html">importhook</a></h1> | |||
| <h3>Navigation</h3> | |||
| <div class="relations"> | |||
| <h3>Related Topics</h3> | |||
| <ul> | |||
| <li><a href="index.html">Documentation overview</a><ul> | |||
| </ul></li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="clearer"></div> | |||
| </div> | |||
| <div class="footer"> | |||
| ©2018, Brett Langdon <me@brett.is>. | |||
| | | |||
| Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.7</a> | |||
| & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.11</a> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1 @@ | |||
| Search.setIndex({docnames:["index"],envversion:53,filenames:["index.rst"],objects:{"":{importhook:[0,0,0,"-"]},importhook:{copy_module:[0,1,1,""],get_module_name:[0,1,1,""],on_import:[0,1,1,""],reload_module:[0,1,1,""],reset_module:[0,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:function"},terms:{"function":0,"import":0,"return":0,"true":0,__spec__:0,any_modul:0,back:0,call:0,certain:0,configur:0,copi:0,copy_attribut:0,copy_modul:0,copy_spec:0,def:0,func:0,get:0,get_hostnam:0,get_module_nam:0,given:0,helper:0,hook:0,hostnam:0,httplib:0,lambda:0,modul:0,module_nam:0,name:0,new_socket:0,none:0,on_any_import:0,on_httplib_import:0,on_import:0,on_socket_import:0,origin:0,pass:0,print:0,python:0,regist:0,reload:0,reload_modul:0,reset:0,reset_modul:0,setattr:0,socket:0,socket_import:0,specifi:0,used:0,version:0,when:0},titles:["importhook"],titleterms:{importhook:0}}) | |||