pub static JS: &'static [u8] =
b"$( document ).ready(function() {\n\n // url\n var url = window.location.pathname;\n\n // Fix back button cache problem\n window.onunload = function(){};\n\n // Set theme\n var theme = store.get(\'mdbook-theme\');\n if (theme === null || theme === undefined) { theme = \'light\'; }\n\n set_theme(theme);\n\n // Syntax highlighting Configuration\n hljs.configure({\n tabReplace: \' \', // 4 spaces\n languages: [], // Languages used for auto-detection\n });\n\n if (window.ace) {\n // language-rust class needs to be removed for editable\n // blocks or highlightjs will capture events\n $(\'code.editable\').removeClass(\'language-rust\');\n\n $(\'code\').not(\'.editable\').each(function(i, block) {\n hljs.highlightBlock(block);\n });\n } else {\n $(\'code\').each(function(i, block) {\n hljs.highlightBlock(block);\n });\n }\n\n // Adding the hljs class gives code blocks the color css\n // even if highlighting doesn\'t apply\n $(\'code\').addClass(\'hljs\');\n\n var KEY_CODES = {\n PREVIOUS_KEY: 37,\n NEXT_KEY: 39,\n SEARCH_KEY: 83\n };\n\n $(document).on(\'keydown\', function (e) {\n if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }\n if ($(\'#searchbar\').is( \":focus\" )) { return; }\n switch (e.keyCode) {\n case KEY_CODES.NEXT_KEY:\n e.preventDefault();\n if($(\'.nav-chapters.next\').length) {\n window.location.href = $(\'.nav-chapters.next\').attr(\'href\');\n }\n break;\n case KEY_CODES.PREVIOUS_KEY:\n e.preventDefault();\n if($(\'.nav-chapters.previous\').length) {\n window.location.href = $(\'.nav-chapters.previous\').attr(\'href\');\n }\n break;\n case KEY_CODES.SEARCH_KEY:\n e.preventDefault();\n $(\'#searchbar\').focus();\n break;\n }\n });\n\n // Interesting DOM Elements\n var sidebar = $(\"#sidebar\");\n\n // Help keyboard navigation by always focusing on page content\n $(\".page\").focus();\n\n // Toggle sidebar\n $(\"#sidebar-toggle\").click(sidebarToggle);\n\n // Hide sidebar on section link click if it occupies large space\n // in relation to the whole screen (phone in portrait)\n $(\"#sidebar a\").click(function(event){\n if (sidebar.width() > window.screen.width * 0.4) {\n sidebarToggle();\n }\n });\n\n // Scroll sidebar to current active section\n var activeSection = sidebar.find(\".active\");\n if(activeSection.length) {\n sidebar.scrollTop(activeSection.offset().top);\n }\n\n // For testing purposes: Index current page\n var searchindex = create_text_searchindex();\n var current_searchterm = \"\";\n var teaser_size_half = 80;\n\n // Searchbar\n $(\"#searchbar\").on(\'keyup\', function (e) {\n var display = $(\'#searchresults\');\n var outer = $(\"#searchresults-outer\");\n\n var searchterm = e.target.value.trim();\n if (searchterm != \"\") {\n // keep searchbar expanded\n $(e.target).addClass(\"active\");\n\n // Don\'t search twice the same\n if (current_searchterm == searchterm) { return; }\n else { current_searchterm = searchterm; }\n\n // Do the actual search\n var results = searchindex.search(searchterm, {\n bool: \"AND\",\n expand: true\n });\n\n // Display search metrics\n var searchheader = \"\";\n if (results.length > 0) {\n searchheader = results.length + \" search results for \'\" + searchterm + \"\':\";\n } else if (results.length == 1) {\n searchheader = results.length + \" search result for \'\" + searchterm + \"\':\";\n } else {\n searchheader = \"No search results for \'\" + searchterm + \"\'.\";\n }\n $(\'#searchresults-header\').text(searchheader);\n\n // Clear and insert results\n var firstterm = searchterm.split(\' \')[0];\n display.empty();\n for(var i = 0, size = results.length; i < size ; i++){\n var result = results[i];\n document.lsd = result.doc;\n var firstoccurence = result.doc.body.search(firstterm);\n var teaser = \"\";\n if (firstoccurence != -1) {\n var teaserstartindex = firstoccurence - teaser_size_half;\n var nextwordindex = result.doc.body.indexOf(\" \", teaserstartindex);\n if (nextwordindex != -1) {\n teaserstartindex = nextwordindex;\n }\n var teaserendindex = firstoccurence + teaser_size_half;\n nextwordindex = result.doc.body.indexOf(\" \", teaserendindex);\n if (nextwordindex != -1) {\n teaserendindex = nextwordindex;\n }\n teaser = (teaserstartindex > 0) ? \"...\" : \"\";\n teaser += result.doc.body.substring(teaserstartindex, teaserendindex) + \"...\";\n } else {\n teaser = result.doc.body.substr(0, 80) + \"...\";\n }\n\n display.append(\'<li><a href=\"\' + result.ref + \'\">\' + result.doc.title + \'</a>: \'\n + teaser + \"</li>\");\n }\n\n // Display and scroll to results\n sidebar.scrollTop(0);\n outer.slideDown();\n } else {\n // searchbar can shrink\n $(e.target).removeClass(\"active\");\n outer.slideUp();\n display.empty();\n }\n });\n\n // Theme button\n $(\"#theme-toggle\").click(function(){\n if($(\'.theme-popup\').length) {\n $(\'.theme-popup\').remove();\n } else {\n var popup = $(\'<div class=\"theme-popup\"></div>\')\n .append($(\'<div class=\"theme\" id=\"light\">Light <span class=\"default\">(default)</span><div>\'))\n .append($(\'<div class=\"theme\" id=\"rust\">Rust</div>\'))\n .append($(\'<div class=\"theme\" id=\"coal\">Coal</div>\'))\n .append($(\'<div class=\"theme\" id=\"navy\">Navy</div>\'))\n .append($(\'<div class=\"theme\" id=\"ayu\">Ayu</div>\'));\n\n\n popup.insertAfter(this);\n\n $(\'.theme\').click(function(){\n var theme = $(this).attr(\'id\');\n set_theme(theme);\n });\n }\n });\n\n // Hide theme selector popup when clicking outside of it\n $(document).click(function(event){\n var popup = $(\'.theme-popup\');\n if(popup.length) {\n var target = $(event.target);\n if(!target.closest(\'.theme\').length && !target.closest(\'#theme-toggle\').length) {\n popup.remove();\n }\n }\n });\n\n function set_theme(theme) {\n let ace_theme;\n\n if (theme == \'coal\' || theme == \'navy\') {\n $(\"[href=\'ayu-highlight.css\']\").prop(\'disabled\', true);\n $(\"[href=\'tomorrow-night.css\']\").prop(\'disabled\', false);\n $(\"[href=\'highlight.css\']\").prop(\'disabled\', true);\n\n ace_theme = \"ace/theme/tomorrow_night\";\n } else if (theme == \'ayu\') {\n $(\"[href=\'ayu-highlight.css\']\").prop(\'disabled\', false);\n $(\"[href=\'tomorrow-night.css\']\").prop(\'disabled\', true);\n $(\"[href=\'highlight.css\']\").prop(\'disabled\', true);\n\n ace_theme = \"ace/theme/tomorrow_night\";\n } else {\n $(\"[href=\'ayu-highlight.css\']\").prop(\'disabled\', true);\n $(\"[href=\'tomorrow-night.css\']\").prop(\'disabled\', true);\n $(\"[href=\'highlight.css\']\").prop(\'disabled\', false);\n\n ace_theme = \"ace/theme/dawn\";\n }\n\n if (window.ace && window.editors) {\n window.editors.forEach(function(editor) {\n editor.setTheme(ace_theme);\n });\n }\n\n store.set(\'mdbook-theme\', theme);\n\n $(\'body\').removeClass().addClass(theme);\n }\n\n\n // Hide Rust code lines prepended with a specific character\n var hiding_character = \"#\";\n\n $(\"code.language-rust\").each(function(i, block){\n\n var code_block = $(this);\n var pre_block = $(this).parent();\n // hide lines\n var lines = code_block.html().split(\"\\n\");\n var first_non_hidden_line = false;\n var lines_hidden = false;\n\n for(var n = 0; n < lines.length; n++){\n if($.trim(lines[n])[0] == hiding_character){\n if(first_non_hidden_line){\n lines[n] = \"<span class=\\\"hidden\\\">\" + \"\\n\" + lines[n].replace(/(\\s*)# ?/, \"$1\") + \"</span>\";\n }\n else {\n lines[n] = \"<span class=\\\"hidden\\\">\" + lines[n].replace(/(\\s*)# ?/, \"$1\") + \"\\n\" + \"</span>\";\n }\n lines_hidden = true;\n }\n else if(first_non_hidden_line) {\n lines[n] = \"\\n\" + lines[n];\n }\n else {\n first_non_hidden_line = true;\n }\n }\n code_block.html(lines.join(\"\"));\n\n // If no lines were hidden, return\n if(!lines_hidden) { return; }\n\n // add expand button\n pre_block.prepend(\"<div class=\\\"buttons\\\"><i class=\\\"fa fa-expand\\\"></i></div>\");\n\n pre_block.find(\"i\").click(function(e){\n if( $(this).hasClass(\"fa-expand\") ) {\n $(this).removeClass(\"fa-expand\").addClass(\"fa-compress\");\n pre_block.find(\"span.hidden\").removeClass(\"hidden\").addClass(\"unhidden\");\n }\n else {\n $(this).removeClass(\"fa-compress\").addClass(\"fa-expand\");\n pre_block.find(\"span.unhidden\").removeClass(\"unhidden\").addClass(\"hidden\");\n }\n });\n });\n\n // Process playpen code blocks\n $(\".playpen\").each(function(block){\n var pre_block = $(this);\n // Add play button\n var buttons = pre_block.find(\".buttons\");\n if( buttons.length === 0 ) {\n pre_block.prepend(\"<div class=\\\"buttons\\\"></div>\");\n buttons = pre_block.find(\".buttons\");\n }\n buttons.prepend(\"<i class=\\\"fa fa-play play-button hidden\\\"></i>\");\n buttons.prepend(\"<i class=\\\"fa fa-copy clip-button\\\"><i class=\\\"tooltiptext\\\"></i></i>\");\n\n let code_block = pre_block.find(\"code\").first();\n if (window.ace && code_block.hasClass(\"editable\")) {\n buttons.prepend(\"<i class=\\\"fa fa-history reset-button\\\"></i>\");\n }\n\n buttons.find(\".play-button\").click(function(e){\n run_rust_code(pre_block);\n });\n buttons.find(\".clip-button\").mouseout(function(e){\n hideTooltip(e.currentTarget);\n });\n buttons.find(\".reset-button\").click(function() {\n if (!window.ace) { return; }\n let editor = window.ace.edit(code_block.get(0));\n editor.setValue(editor.originalCode);\n editor.clearSelection();\n });\n });\n\n var clipboardSnippets = new Clipboard(\'.clip-button\', {\n text: function(trigger) {\n hideTooltip(trigger);\n let playpen = $(trigger).parents(\".playpen\");\n return playpen_text(playpen);\n }\n });\n clipboardSnippets.on(\'success\', function(e) {\n e.clearSelection();\n showTooltip(e.trigger, \"Copied!\");\n });\n clipboardSnippets.on(\'error\', function(e) {\n showTooltip(e.trigger, \"Clipboard error!\");\n });\n\n $.ajax({\n url: \"https://play.rust-lang.org/meta/crates\",\n method: \"POST\",\n crossDomain: true,\n dataType: \"json\",\n contentType: \"application/json\",\n success: function(response){\n // get list of crates available in the rust playground\n let playground_crates = response.crates.map(function(item) {return item[\"id\"];} );\n $(\".playpen\").each(function(block) {\n handle_crate_list_update($(this), playground_crates);\n });\n },\n });\n\n});\n\nfunction playpen_text(playpen) {\n let code_block = playpen.find(\"code\").first();\n\n if (window.ace && code_block.hasClass(\"editable\")) {\n let editor = window.ace.edit(code_block.get(0));\n return editor.getValue();\n } else {\n return code_block.get(0).textContent;\n }\n}\n\nfunction handle_crate_list_update(playpen_block, playground_crates) {\n // update the play buttons after receiving the response\n update_play_button(playpen_block, playground_crates);\n\n // and install on change listener to dynamically update ACE editors\n if (window.ace) {\n let code_block = playpen_block.find(\"code\").first();\n if (code_block.hasClass(\"editable\")) {\n let editor = window.ace.edit(code_block.get(0));\n editor.on(\"change\", function(e){\n update_play_button(playpen_block, playground_crates);\n });\n }\n }\n}\n\n// updates the visibility of play button based on `no_run` class and\n// used crates vs ones available on http://play.rust-lang.org\nfunction update_play_button(pre_block, playground_crates) {\n var play_button = pre_block.find(\".play-button\");\n\n var classes = pre_block.find(\"code\").attr(\"class\").split(\" \");\n // skip if code is `no_run`\n if (classes.indexOf(\"no_run\") > -1) {\n play_button.addClass(\"hidden\");\n return;\n }\n\n // get list of `extern crate`\'s from snippet\n var txt = playpen_text(pre_block);\n var re = /extern\\s+crate\\s+([a-zA-Z_0-9]+)\\s*;/g;\n var snippet_crates = [];\n while (item = re.exec(txt)) {\n snippet_crates.push(item[1]);\n }\n\n // check if all used crates are available on play.rust-lang.org\n var all_available = snippet_crates.every(function(elem) {\n return playground_crates.indexOf(elem) > -1;\n });\n\n if (all_available) {\n play_button.removeClass(\"hidden\");\n } else {\n play_button.addClass(\"hidden\");\n }\n}\n\nfunction hideTooltip(elem) {\n elem.firstChild.innerText=\"\";\n elem.setAttribute(\'class\', \'fa fa-copy clip-button\');\n}\n\nfunction showTooltip(elem, msg) {\n elem.firstChild.innerText=msg;\n elem.setAttribute(\'class\', \'fa fa-copy tooltipped\');\n}\n\nfunction sidebarToggle() {\n var html = $(\"html\");\n if ( html.hasClass(\"sidebar-hidden\") ) {\n html.removeClass(\"sidebar-hidden\").addClass(\"sidebar-visible\");\n store.set(\'mdbook-sidebar\', \'visible\');\n } else if ( html.hasClass(\"sidebar-visible\") ) {\n html.removeClass(\"sidebar-visible\").addClass(\"sidebar-hidden\");\n store.set(\'mdbook-sidebar\', \'hidden\');\n } else {\n if($(\"#sidebar\").position().left === 0){\n html.addClass(\"sidebar-hidden\");\n store.set(\'mdbook-sidebar\', \'hidden\');\n } else {\n html.addClass(\"sidebar-visible\");\n store.set(\'mdbook-sidebar\', \'visible\');\n }\n }\n}\n\nfunction run_rust_code(code_block) {\n var result_block = code_block.find(\".result\");\n if(result_block.length === 0) {\n code_block.append(\"<code class=\\\"result hljs language-bash\\\"></code>\");\n result_block = code_block.find(\".result\");\n }\n\n let text = playpen_text(code_block);\n\n var params = {\n\tchannel: \"stable\",\n\tmode: \"debug\",\n\tcrateType: \"bin\",\n\ttests: false,\n\tcode: text,\n }\n\n if(text.indexOf(\"#![feature\") !== -1) {\n params.channel = \"nightly\";\n }\n\n result_block.text(\"Running...\");\n\n $.ajax({\n url: \"https://play.rust-lang.org/execute\",\n method: \"POST\",\n crossDomain: true,\n dataType: \"json\",\n contentType: \"application/json\",\n data: JSON.stringify(params),\n timeout: 15000,\n success: function(response){\n result_block.text(response.success ? response.stdout : response.stderr);\n },\n error: function(qXHR, textStatus, errorThrown){\n result_block.text(\"Playground communication \" + textStatus);\n },\n });\n}\n\nfunction create_text_searchindex() {\n var searchindex = elasticlunr(function () {\n this.addField(\'body\');\n this.addField(\'title\');\n this.setRef(\'id\');\n });\n var content = $(\"#content\");\n var paragraphs = content.children();\n var curr_title = \"\";\n var curr_body = \"\";\n var curr_ref = \"\";\n var push = function(ref) {\n if ((curr_title.length > 0 || curr_body.length > 0) && curr_ref.length > 0) {\n var doc = {\n \"id\": curr_ref,\n \"body\": curr_body,\n \"title\": curr_title\n }\n searchindex.addDoc(doc);\n }\n curr_body = \"\";\n curr_title = \"\";\n curr_ref = \"\";\n };\n paragraphs.each(function(index, element) {\n // todo uppercase\n var el = $(element);\n if (el.prop(\'nodeName\').toUpperCase() == \"A\") {\n // new header, push old paragraph to index\n push(index);\n curr_title = el.text();\n curr_ref = el.attr(\'href\');\n } else {\n curr_body += \" \\n \" + el.text();\n }\n // last paragraph\n if (index == paragraphs.length - 1) {\n push(index);\n }\n });\n return searchindex;\n}"