// Local js definitions:
/* global addClass, getSettingValue, hasClass, updateLocalStorage */
/* global onEachLazy, removeClass, getVar, nonnull */

"use strict";

// The amount of time that the cursor must remain still over a hover target before
// revealing a tooltip.
//
// https://www.nngroup.com/articles/timing-exposing-content/
window.RUSTDOC_TOOLTIP_HOVER_MS = 300;
window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS = 450;

/**
 * Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL
 * for a resource under the root-path, with the resource-suffix.
 *
 * @param {string} basename
 * @param {string} extension
 */
function resourcePath(basename, extension) {
    return getVar("root-path") + basename + getVar("resource-suffix") + extension;
}

function hideMain() {
    addClass(document.getElementById(MAIN_ID), "hidden");
    const toggle = document.getElementById("toggle-all-docs");
    if (toggle) {
        toggle.setAttribute("disabled", "disabled");
    }
}

function showMain() {
    const main = document.getElementById(MAIN_ID);
    if (!main) {
        return;
    }
    removeClass(main, "hidden");
    const mainHeading = main.querySelector(".main-heading");
    if (mainHeading && window.searchState.rustdocToolbar) {
        if (window.searchState.rustdocToolbar.parentElement) {
            window.searchState.rustdocToolbar.parentElement.removeChild(
                window.searchState.rustdocToolbar,
            );
        }
        mainHeading.appendChild(window.searchState.rustdocToolbar);
    }
    const toggle = document.getElementById("toggle-all-docs");
    if (toggle) {
        toggle.removeAttribute("disabled");
    }
}

window.rootPath = getVar("root-path");
window.currentCrate = getVar("current-crate");

/**
 * Gets the human-readable string for the virtual-key code of the
 * given KeyboardEvent, ev.
 *
 * This function is meant as a polyfill for KeyboardEvent#key,
 * since it is not supported in IE 11 or Chrome for Android. We also test for
 * KeyboardEvent#keyCode because the handleShortcut handler is
 * also registered for the keydown event, because Blink doesn't fire
 * keypress on hitting the Escape key.
 *
 * So I guess you could say things are getting pretty interoperable.
 *
 * @param {KeyboardEvent} ev
 * @returns {string}
 */
function getVirtualKey(ev) {
    if ("key" in ev && typeof ev.key !== "undefined") {
        return ev.key;
    }

    const c = ev.charCode || ev.keyCode;
    if (c === 27) {
        return "Escape";
    }
    return String.fromCharCode(c);
}

const MAIN_ID = "main-content";
const ALTERNATIVE_DISPLAY_ID = "alternative-display";
const NOT_DISPLAYED_ID = "not-displayed";

// Returns the current URL without any query parameter or hash.
function getNakedUrl() {
    return window.location.href.split("?")[0].split("#")[0];
}

/**
 * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode`
 * doesn't have a parent node.
 *
 * @param {HTMLElement} newNode
 * @param {HTMLElement & { parentNode: HTMLElement }} referenceNode
 */
function insertAfter(newNode, referenceNode) {
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

/**
 * This function creates a new `<section>` with the given `id` and `classes` if it doesn't already
 * exist.
 *
 * More information about this in `switchDisplayedElement` documentation.
 *
 * @param {string} id
 * @param {string} classes
 */
function getOrCreateSection(id, classes) {
    let el = document.getElementById(id);

    if (!el) {
        el = document.createElement("section");
        el.id = id;
        el.className = classes;
        // @ts-expect-error
        insertAfter(el, document.getElementById(MAIN_ID));
    }
    return el;
}

/**
 * Returns the `<section>` element which contains the displayed element.
 *
 * @return {HTMLElement}
 */
function getAlternativeDisplayElem() {
    return getOrCreateSection(ALTERNATIVE_DISPLAY_ID, "content hidden");
}

/**
 * Returns the `<section>` element which contains the not-displayed elements.
 *
 * @return {HTMLElement}
 */
function getNotDisplayedElem() {
    return getOrCreateSection(NOT_DISPLAYED_ID, "hidden");
}

/**
 * To nicely switch between displayed "extra" elements (such as search results or settings menu)
 * and to alternate between the displayed and not displayed elements, we hold them in two different
 * `<section>` elements. They work in pair: one holds the hidden elements while the other
 * contains the displayed element (there can be only one at the same time!). So basically, we switch
 * elements between the two `<section>` elements.
 *
 * @param {Element|null} elemToDisplay
 */
function switchDisplayedElement(elemToDisplay) {
    const el = getAlternativeDisplayElem();

    if (el.children.length > 0) {
        // @ts-expect-error
        getNotDisplayedElem().appendChild(el.firstElementChild);
    }
    if (elemToDisplay === null) {
        addClass(el, "hidden");
        showMain();
        return;
    }
    el.appendChild(elemToDisplay);
    hideMain();
    removeClass(el, "hidden");

    const mainHeading = elemToDisplay.querySelector(".main-heading");
    if (mainHeading && window.searchState.rustdocToolbar) {
        if (window.searchState.rustdocToolbar.parentElement) {
            window.searchState.rustdocToolbar.parentElement.removeChild(
                window.searchState.rustdocToolbar,
            );
        }
        mainHeading.appendChild(window.searchState.rustdocToolbar);
    }
}

function browserSupportsHistoryApi() {
    return window.history && typeof window.history.pushState === "function";
}

/**
 * Download CSS from the web without making it the active stylesheet.
 * We use this in the settings popover so that you don't get FOUC when switching.
 *
 * @param {string} cssUrl
 */
function preLoadCss(cssUrl) {
    // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
    const link = document.createElement("link");
    link.href = cssUrl;
    link.rel = "preload";
    link.as = "style";
    document.getElementsByTagName("head")[0].appendChild(link);
}

(function() {
    const isHelpPage = window.location.pathname.endsWith("/help.html");

    /**
     * Run a JavaScript file asynchronously.
     * @param {string} url
     * @param {function(): any} errorCallback
     */
    function loadScript(url, errorCallback) {
        const script = document.createElement("script");
        script.src = url;
        if (errorCallback !== undefined) {
            script.onerror = errorCallback;
        }
        document.head.append(script);
    }

    onEachLazy(document.querySelectorAll(".settings-menu"), settingsMenu => {
        /** @param {MouseEvent} event */
        settingsMenu.querySelector("a").onclick = event => {
            if (event.ctrlKey || event.altKey || event.metaKey) {
                return;
            }
            window.hideAllModals(false);
            addClass(settingsMenu, "rotate");
            event.preventDefault();
            // Sending request for the CSS and the JS files at the same time so it will
            // hopefully be loaded when the JS will generate the settings content.
            // @ts-expect-error
            loadScript(getVar("static-root-path") + getVar("settings-js"));
            // Pre-load all theme CSS files, so that switching feels seamless.
            //
            // When loading settings.html as a standalone page, the equivalent HTML is
            // generated in context.rs.
            setTimeout(() => {
                // @ts-expect-error
                const themes = getVar("themes").split(",");
                for (const theme of themes) {
                    // if there are no themes, do nothing
                    // "".split(",") == [""]
                    if (theme !== "") {
                        preLoadCss(getVar("root-path") + theme + ".css");
                    }
                }
            }, 0);
        };
    });

    window.searchState = {
        rustdocToolbar: document.querySelector("rustdoc-toolbar"),
        loadingText: "Loading search results...",
        inputElement: () => {
            let el = document.getElementsByClassName("search-input")[0];
            if (!el) {
                const out = nonnull(nonnull(window.searchState.outputElement()).parentElement);
                const hdr = document.createElement("div");
                hdr.className = "main-heading search-results-main-heading";
                const params = window.searchState.getQueryStringParams();
                const autofocusParam = params.search === "" ? "autofocus" : "";
                hdr.innerHTML = `<nav class="sub">
                    <form class="search-form loading">
                        <span></span> <!-- This empty span is a hacky fix for Safari: see #93184 -->
                        <input
                            ${autofocusParam}
                            class="search-input"
                            name="search"
                            aria-label="Run search in the documentation"
                            autocomplete="off"
                            spellcheck="false"
                            placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…"
                            type="search">
                    </form>
                </nav><div class="search-switcher"></div>`;
                out.insertBefore(hdr, window.searchState.outputElement());
                el = document.getElementsByClassName("search-input")[0];
            }
            if (el instanceof HTMLInputElement) {
                return el;
            }
            return null;
        },
        containerElement: () => {
            let el = document.getElementById("search");
            if (!el) {
                el = document.createElement("section");
                el.id = "search";
                getNotDisplayedElem().appendChild(el);
            }
            return el;
        },
        outputElement: () => {
            const container = window.searchState.containerElement();
            if (!container) {
                return null;
            }
            let el = container.querySelector(".search-out");
            if (!el) {
                el = document.createElement("div");
                el.className = "search-out";
                container.appendChild(el);
            }
            return el;
        },
        title: document.title,
        titleBeforeSearch: document.title,
        timeout: null,
        // On the search screen, so you remain on the last tab you opened.
        //
        // 0 for "In Names"
        // 1 for "In Parameters"
        // 2 for "In Return Types"
        currentTab: 0,
        // tab and back preserves the element that was focused.
        focusedByTab: [null, null, null],
        clearInputTimeout: () => {
            if (window.searchState.timeout !== null) {
                clearTimeout(window.searchState.timeout);
                window.searchState.timeout = null;
            }
        },
        isDisplayed: () => {
            const container = window.searchState.containerElement();
            if (!container) {
                return false;
            }
            return !!container.parentElement && container.parentElement.id ===
                ALTERNATIVE_DISPLAY_ID;
        },
        // Sets the focus on the search bar at the top of the page
        focus: () => {
            const inputElement = window.searchState.inputElement();
            window.searchState.showResults();
            if (inputElement) {
                inputElement.focus();
                // Avoid glitch if something focuses the search button after clicking.
                requestAnimationFrame(() => inputElement.focus());
            }
        },
        // Removes the focus from the search bar.
        defocus: () => {
            nonnull(window.searchState.inputElement()).blur();
        },
        toggle: () => {
            if (window.searchState.isDisplayed()) {
                window.searchState.defocus();
                window.searchState.hideResults();
            } else {
                window.searchState.focus();
            }
        },
        showResults: () => {
            document.title = window.searchState.title;
            if (window.searchState.isDisplayed()) {
                return;
            }
            const search = window.searchState.containerElement();
            switchDisplayedElement(search);
            const btn = document.querySelector("#search-button a");
            if (browserSupportsHistoryApi() && btn instanceof HTMLAnchorElement &&
                window.searchState.getQueryStringParams().search === undefined
            ) {
                history.pushState(null, "", btn.href);
            }
            const btnLabel = document.querySelector("#search-button a span.label");
            if (btnLabel) {
                btnLabel.innerHTML = "Exit";
            }
        },
        removeQueryParameters: () => {
            // We change the document title.
            document.title = window.searchState.titleBeforeSearch;
            if (browserSupportsHistoryApi()) {
                history.replaceState(null, "", getNakedUrl() + window.location.hash);
            }
        },
        hideResults: () => {
            switchDisplayedElement(null);
            // We also remove the query parameter from the URL.
            window.searchState.removeQueryParameters();
            const btnLabel = document.querySelector("#search-button a span.label");
            if (btnLabel) {
                btnLabel.innerHTML = "Search";
            }
        },
        getQueryStringParams: () => {
            /** @type {Object.<any, string>} */
            const params = {};
            window.location.search.substring(1).split("&").
                map(s => {
                    // https://github.com/rust-lang/rust/issues/119219
                    const pair = s.split("=").map(x => x.replace(/\+/g, " "));
                    params[decodeURIComponent(pair[0])] =
                        typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
                });
            return params;
        },
        setup: () => {
            let searchLoaded = false;
            const search_input = window.searchState.inputElement();
            if (!search_input) {
                return;
            }
            // If you're browsing the nightly docs, the page might need to be refreshed for the
            // search to work because the hash of the JS scripts might have changed.
            function sendSearchForm() {
                // @ts-expect-error
                document.getElementsByClassName("search-form")[0].submit();
            }
            function loadSearch() {
                if (!searchLoaded) {
                    searchLoaded = true;
                    window.rr_ = data => {
                        window.searchIndex = data;
                    };
                    if (!window.StringdexOnload) {
                        window.StringdexOnload = [];
                    }
                    window.StringdexOnload.push(() => {
                        loadScript(
                            // @ts-expect-error
                            getVar("static-root-path") + getVar("search-js"),
                            sendSearchForm,
                        );
                    });
                    // @ts-expect-error
                    loadScript(getVar("static-root-path") + getVar("stringdex-js"), sendSearchForm);
                    loadScript(resourcePath("search.index/root", ".js"), sendSearchForm);
                }
            }

            search_input.addEventListener("focus", () => {
                loadSearch();
            });

            const btn = document.getElementById("search-button");
            if (btn) {
                btn.onclick = event => {
                    if (event.ctrlKey || event.altKey || event.metaKey) {
                        return;
                    }
                    event.preventDefault();
                    window.searchState.toggle();
                    loadSearch();
                };
            }

            // Push and pop states are used to add search results to the browser
            // history.
            if (browserSupportsHistoryApi()) {
                // Store the previous <title> so we can revert back to it later.
                const previousTitle = document.title;

                window.addEventListener("popstate", e => {
                    const params = window.searchState.getQueryStringParams();
                    // Revert to the previous title manually since the History
                    // API ignores the title parameter.
                    document.title = previousTitle;
                    // Synchronize search bar with query string state and
                    // perform the search. This will empty the bar if there's
                    // nothing there, which lets you really go back to a
                    // previous state with nothing in the bar.
                    const inputElement = window.searchState.inputElement();
                    if (params.search !== undefined && inputElement !== null) {
                        loadSearch();
                        inputElement.value = params.search;
                        // Some browsers fire "onpopstate" for every page load
                        // (Chrome), while others fire the event only when actually
                        // popping a state (Firefox), which is why search() is
                        // called both here and at the end of the startSearch()
                        // function.
                        e.preventDefault();
                        window.searchState.showResults();
                        if (params.search === "") {
                            window.searchState.focus();
                        }
                    } else {
                        // When browsing back from search results the main page
                        // visibility must be reset.
                        window.searchState.hideResults();
                    }
                });
            }

            // This is required in firefox to avoid this problem: Navigating to a search result
            // with the keyboard, hitting enter, and then hitting back would take you back to
            // the doc page, rather than the search that should overlay it.
            // This was an interaction between the back-forward cache and our handlers
            // that try to sync state between the URL and the search input. To work around it,
            // do a small amount of re-init on page show.
            window.onpageshow = () => {
                const inputElement = window.searchState.inputElement();
                const qSearch = window.searchState.getQueryStringParams().search;
                if (qSearch !== undefined && inputElement !== null) {
                    if (inputElement.value === "") {
                        inputElement.value = qSearch;
                    }
                    window.searchState.showResults();
                    if (qSearch === "") {
                        loadSearch();
                        window.searchState.focus();
                    }
                } else {
                    window.searchState.hideResults();
                }
            };

            const params = window.searchState.getQueryStringParams();
            if (params.search !== undefined) {
                window.searchState.setLoadingSearch();
                loadSearch();
            }
        },
        setLoadingSearch: () => {
            const search = window.searchState.outputElement();
            nonnull(search).innerHTML = "<h3 class=\"search-loading\">" +
                window.searchState.loadingText + "</h3>";
            window.searchState.showResults();
        },
        descShards: new Map(),
        loadDesc: async function({descShard, descIndex}) {
            if (descShard.promise === null) {
                descShard.promise = new Promise((resolve, reject) => {
                    // The `resolve` callback is stored in the `descShard`
                    // object, which is itself stored in `this.descShards` map.
                    // It is called in `loadedDescShard` by the
                    // search.desc script.
                    descShard.resolve = resolve;
                    const ds = descShard;
                    const fname = `${ds.crate}-desc-${ds.shard}-`;
                    const url = resourcePath(
                        `search.desc/${descShard.crate}/${fname}`,
                        ".js",
                    );
                    loadScript(url, reject);
                });
            }
            const list = await descShard.promise;
            return list[descIndex];
        },
        loadedDescShard: function(crate, shard, data) {
            // If loadedDescShard gets called, then the library must have been declared.
            // @ts-expect-error
            this.descShards.get(crate)[shard].resolve(data.split("\n"));
        },
    };

    const toggleAllDocsId = "toggle-all-docs";
    let savedHash = "";

    /**
     * @param {HashChangeEvent|null} ev
     */
    function handleHashes(ev) {
        if (ev !== null && window.searchState.isDisplayed() && ev.newURL) {
            // This block occurs when clicking on an element in the navbar while
            // in a search.
            switchDisplayedElement(null);
            const hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
            if (browserSupportsHistoryApi()) {
                // `window.location.search`` contains all the query parameters, not just `search`.
                history.replaceState(null, "",
                    getNakedUrl() + window.location.search + "#" + hash);
            }
            const elem = document.getElementById(hash);
            if (elem) {
                elem.scrollIntoView();
            }
        }
        // This part is used in case an element is not visible.
        const pageId = window.location.hash.replace(/^#/, "");
        if (savedHash !== pageId) {
            savedHash = pageId;
            if (pageId !== "") {
                expandSection(pageId);
            }
        }
        if (savedHash.startsWith("impl-")) {
            // impl-disambiguated links, used by the search engine
            // format: impl-X[-for-Y]/method.WHATEVER
            // turn this into method.WHATEVER[-NUMBER]
            const splitAt = savedHash.indexOf("/");
            if (splitAt !== -1) {
                const implId = savedHash.slice(0, splitAt);
                const assocId = savedHash.slice(splitAt + 1);
                const implElems = document.querySelectorAll(
                    `details > summary > section[id^="${implId}"]`,
                );
                onEachLazy(implElems, implElem => {
                    const numbered = /^(.+?)-([0-9]+)$/.exec(implElem.id);
                    if (implElem.id !== implId && (!numbered || numbered[1] !== implId)) {
                        return false;
                    }
                    return onEachLazy(implElem.parentElement.parentElement.querySelectorAll(
                        `[id^="${assocId}"]`),
                        item => {
                            const numbered = /^(.+?)-([0-9]+)$/.exec(item.id);
                            if (item.id === assocId || (numbered && numbered[1] === assocId)) {
                                openParentDetails(item);
                                item.scrollIntoView();
                                // Let the section expand itself before trying to highlight
                                setTimeout(() => {
                                    window.location.replace("#" + item.id);
                                }, 0);
                                return true;
                            }
                        },
                    );
                });
            }
        }
    }

    /**
     * @param {HashChangeEvent|null} ev
     */
    function onHashChange(ev) {
        // If we're in mobile mode, we should hide the sidebar in any case.
        hideSidebar();
        handleHashes(ev);
    }

    /**
     * @param {HTMLElement|null} elem
     */
    function openParentDetails(elem) {
        while (elem) {
            if (elem.tagName === "DETAILS") {
                // @ts-expect-error
                elem.open = true;
            }
            elem = elem.parentElement;
        }
    }

    /**
     * @param {string} id
     */
    function expandSection(id) {
        openParentDetails(document.getElementById(id));
    }

    /**
     * @param {KeyboardEvent} ev
     */
    function handleEscape(ev) {
        window.searchState.clearInputTimeout();
        window.searchState.hideResults();
        ev.preventDefault();
        window.searchState.defocus();
        window.hideAllModals(true); // true = reset focus for tooltips
    }

    /**
     * @param {KeyboardEvent} ev
     */
    function handleShortcut(ev) {
        // Don't interfere with browser shortcuts
        const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
        if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {
            return;
        }

        if (document.activeElement &&
            document.activeElement.tagName === "INPUT" &&
            // @ts-expect-error
            document.activeElement.type !== "checkbox" &&
            // @ts-expect-error
            document.activeElement.type !== "radio") {
            switch (getVirtualKey(ev)) {
            case "Escape":
                handleEscape(ev);
                break;
            }
        } else {
            switch (getVirtualKey(ev)) {
            case "Escape":
                handleEscape(ev);
                break;

            case "s":
            case "S":
            case "/":
                ev.preventDefault();
                window.searchState.focus();
                break;

            case "+":
            case "=":
                ev.preventDefault();
                expandAllDocs();
                break;
            case "-":
                ev.preventDefault();
                collapseAllDocs(false);
                break;
            case "_":
                ev.preventDefault();
                collapseAllDocs(true);
                break;

            case "?":
                showHelp();
                break;

            default:
                break;
            }
        }
    }

    document.addEventListener("keypress", handleShortcut);
    document.addEventListener("keydown", handleShortcut);

    function addSidebarItems() {
        if (!window.SIDEBAR_ITEMS) {
            return;
        }
        const sidebar = document.getElementById("rustdoc-modnav");

        /**
         * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
         *
         * @param {string} shortty - A short type name, like "primitive", "mod", or "macro"
         * @param {string} id - The HTML id of the corresponding section on the module page.
         * @param {string} longty - A long, capitalized, plural name, like "Primitive Types",
         *                          "Modules", or "Macros".
         */
        function block(shortty, id, longty) {
            // @ts-expect-error
            const filtered = window.SIDEBAR_ITEMS[shortty];
            if (!filtered) {
                return;
            }

            const modpath = hasClass(document.querySelector(".rustdoc"), "mod") ? "../" : "";

            const h3 = document.createElement("h3");
            h3.innerHTML = `<a href="${modpath}index.html#${id}">${longty}</a>`;
            const ul = document.createElement("ul");
            ul.className = "block " + shortty;

            for (const name of filtered) {
                let path;
                if (shortty === "mod") {
                    path = `${modpath}${name}/index.html`;
                } else {
                    path = `${modpath}${shortty}.${name}.html`;
                }
                let current_page = document.location.href.toString();
                if (current_page.endsWith("/")) {
                    current_page += "index.html";
                }
                const link = document.createElement("a");
                link.href = path;
                link.textContent = name;
                const li = document.createElement("li");
                // Don't "optimize" this to just use `path`.
                // We want the browser to normalize this into an absolute URL.
                if (link.href === current_page) {
                    li.classList.add("current");
                }
                li.appendChild(link);
                ul.appendChild(li);
            }
            // @ts-expect-error
            sidebar.appendChild(h3);
            // @ts-expect-error
            sidebar.appendChild(ul);
        }

        if (sidebar) {
            // keep this synchronized with ItemSection::ALL in html/render/mod.rs
            // Re-exports aren't shown here, because they don't have child pages
            //block("reexport", "reexports", "Re-exports");
            block("primitive", "primitives", "Primitive Types");
            block("mod", "modules", "Modules");
            block("macro", "macros", "Macros");
            block("struct", "structs", "Structs");
            block("enum", "enums", "Enums");
            block("constant", "constants", "Constants");
            block("static", "static", "Statics");
            block("trait", "traits", "Traits");
            block("fn", "functions", "Functions");
            block("type", "types", "Type Aliases");
            block("union", "unions", "Unions");
            // No point, because these items don't appear in modules
            //block("impl", "impls", "Implementations");
            //block("tymethod", "tymethods", "Type Methods");
            //block("method", "methods", "Methods");
            //block("structfield", "fields", "Fields");
            //block("variant", "variants", "Variants");
            //block("associatedtype", "associated-types", "Associated Types");
            //block("associatedconstant", "associated-consts", "Associated Constants");
            block("foreigntype", "foreign-types", "Foreign Types");
            block("keyword", "keywords", "Keywords");
            block("attribute", "attributes", "Attributes");
            block("attr", "attributes", "Attribute Macros");
            block("derive", "derives", "Derive Macros");
            block("traitalias", "trait-aliases", "Trait Aliases");
        }
    }

    // <https://github.com/search?q=repo%3Arust-lang%2Frust+[RUSTDOCIMPL]+trait.impl&type=code>
    window.register_implementors = imp => {
        const implementors = document.getElementById("implementors-list");
        const synthetic_implementors = document.getElementById("synthetic-implementors-list");
        const inlined_types = new Set();

        const TEXT_IDX = 0;
        const SYNTHETIC_IDX = 1;
        const TYPES_IDX = 2;

        if (synthetic_implementors) {
            // This `inlined_types` variable is used to avoid having the same implementation
            // showing up twice. For example "String" in the "Sync" doc page.
            //
            // By the way, this is only used by and useful for traits implemented automatically
            // (like "Send" and "Sync").
            onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => {
                const aliases = el.getAttribute("data-aliases");
                if (!aliases) {
                    return;
                }
                // @ts-expect-error
                aliases.split(",").forEach(alias => {
                    inlined_types.add(alias);
                });
            });
        }

        // @ts-expect-error
        let currentNbImpls = implementors.getElementsByClassName("impl").length;
        // @ts-expect-error
        const traitName = document.querySelector(".main-heading h1 > .trait").textContent;
        const baseIdName = "impl-" + traitName + "-";
        const libs = Object.getOwnPropertyNames(imp);
        // We don't want to include impls from this JS file, when the HTML already has them.
        // The current crate should always be ignored. Other crates that should also be
        // ignored are included in the attribute `data-ignore-extern-crates`.
        const script = document
            .querySelector("script[data-ignore-extern-crates]");
        const ignoreExternCrates = new Set(
            // @ts-expect-error
            (script ? script.getAttribute("data-ignore-extern-crates") : "").split(","),
        );
        for (const lib of libs) {
            if (lib === window.currentCrate || ignoreExternCrates.has(lib)) {
                continue;
            }
            const structs = imp[lib];

            struct_loop:
            for (const struct of structs) {
                const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors;

                // The types list is only used for synthetic impls.
                // If this changes, `main.js` and `write_shared.rs` both need changed.
                if (struct[SYNTHETIC_IDX]) {
                    for (const struct_type of struct[TYPES_IDX]) {
                        if (inlined_types.has(struct_type)) {
                            continue struct_loop;
                        }
                        inlined_types.add(struct_type);
                    }
                }

                const code = document.createElement("h3");
                code.innerHTML = struct[TEXT_IDX];
                addClass(code, "code-header");

                onEachLazy(code.getElementsByTagName("a"), elem => {
                    const href = elem.getAttribute("href");

                    if (href && !href.startsWith("#") && !/^(?:[a-z+]+:)?\/\//.test(href)) {
                        elem.setAttribute("href", window.rootPath + href);
                    }
                });

                const currentId = baseIdName + currentNbImpls;
                const anchor = document.createElement("a");
                anchor.href = "#" + currentId;
                addClass(anchor, "anchor");

                const display = document.createElement("div");
                display.id = currentId;
                addClass(display, "impl");
                display.appendChild(anchor);
                display.appendChild(code);
                // @ts-expect-error
                list.appendChild(display);
                currentNbImpls += 1;
            }
        }
    };
    if (window.pending_implementors) {
        window.register_implementors(window.pending_implementors);
    }

    /**
     * <https://github.com/search?q=repo%3Arust-lang%2Frust+[RUSTDOCIMPL]+type.impl&type=code>
     *
     * [RUSTDOCIMPL] type.impl
     *
     * This code inlines implementations into the type alias docs at runtime. It's done at
     * runtime because some crates have many type aliases and many methods, and we don't want
     * to generate *O*`(types*methods)` HTML text. The data inside is mostly HTML fragments,
     * wrapped in JSON.
     *
     * - It only includes docs generated for the current crate. This function accepts an
     *   object mapping crate names to the set of impls.
     *
     * - It filters down to the set of applicable impls. The Rust type checker is used to
     *   tag each HTML blob with the set of type aliases that can actually use it, so the
     *   JS only needs to consult the attached list of type aliases.
     *
     * - It renames the ID attributes, to avoid conflicting IDs in the resulting DOM.
     *
     * - It adds the necessary items to the sidebar. If it's an inherent impl, that means
     *   adding methods, associated types, and associated constants. If it's a trait impl,
     *   that means adding it to the trait impl sidebar list.
     *
     * - It adds the HTML block itself. If it's an inherent impl, it goes after the type
     *   alias's own inherent impls. If it's a trait impl, it goes in the Trait
     *   Implementations section.
     *
     * - After processing all of the impls, it sorts the sidebar items by name.
     *
     * @param {rustdoc.TypeImpls} imp
     */
    window.register_type_impls = imp => {
        // @ts-expect-error
        if (!imp || !imp[window.currentCrate]) {
            return;
        }
        window.pending_type_impls = undefined;
        const idMap = new Map();

        let implementations = document.getElementById("implementations-list");
        let trait_implementations = document.getElementById("trait-implementations-list");
        let trait_implementations_header = document.getElementById("trait-implementations");

        // We want to include the current type alias's impls, and no others.
        const script = document.querySelector("script[data-self-path]");
        const selfPath = script ? script.getAttribute("data-self-path") : null;

        // These sidebar blocks need filled in, too.
        const mainContent = document.querySelector("#main-content");
        const sidebarSection = document.querySelector(".sidebar section");
        let methods = document.querySelector(".sidebar .block.method");
        let associatedTypes = document.querySelector(".sidebar .block.associatedtype");
        let associatedConstants = document.querySelector(".sidebar .block.associatedconstant");
        let sidebarTraitList = document.querySelector(".sidebar .block.trait-implementation");

        // @ts-expect-error
        for (const impList of imp[window.currentCrate]) {
            const types = impList.slice(2);
            const text = impList[0];
            const isTrait = impList[1] !== 0;
            const traitName = impList[1];
            if (types.indexOf(selfPath) === -1) {
                continue;
            }
            let outputList = isTrait ? trait_implementations : implementations;
            if (outputList === null) {
                const outputListName = isTrait ? "Trait Implementations" : "Implementations";
                const outputListId = isTrait ?
                    "trait-implementations-list" :
                    "implementations-list";
                const outputListHeaderId = isTrait ? "trait-implementations" : "implementations";
                const outputListHeader = document.createElement("h2");
                outputListHeader.id = outputListHeaderId;
                outputListHeader.innerText = outputListName;
                outputList = document.createElement("div");
                outputList.id = outputListId;
                if (isTrait) {
                    const link = document.createElement("a");
                    link.href = `#${outputListHeaderId}`;
                    link.innerText = "Trait Implementations";
                    const h = document.createElement("h3");
                    h.appendChild(link);
                    trait_implementations = outputList;
                    trait_implementations_header = outputListHeader;
                    // @ts-expect-error
                    sidebarSection.appendChild(h);
                    sidebarTraitList = document.createElement("ul");
                    sidebarTraitList.className = "block trait-implementation";
                    // @ts-expect-error
                    sidebarSection.appendChild(sidebarTraitList);
                    // @ts-expect-error
                    mainContent.appendChild(outputListHeader);
                    // @ts-expect-error
                    mainContent.appendChild(outputList);
                } else {
                    implementations = outputList;
                    if (trait_implementations) {
                        // @ts-expect-error
                        mainContent.insertBefore(outputListHeader, trait_implementations_header);
                        // @ts-expect-error
                        mainContent.insertBefore(outputList, trait_implementations_header);
                    } else {
                        const mainContent = document.querySelector("#main-content");
                        // @ts-expect-error
                        mainContent.appendChild(outputListHeader);
                        // @ts-expect-error
                        mainContent.appendChild(outputList);
                    }
                }
            }
            const template = document.createElement("template");
            template.innerHTML = text;

            onEachLazy(template.content.querySelectorAll("a"), elem => {
                const href = elem.getAttribute("href");

                if (href && !href.startsWith("#") && !/^(?:[a-z+]+:)?\/\//.test(href)) {
                    elem.setAttribute("href", window.rootPath + href);
                }
            });
            onEachLazy(template.content.querySelectorAll("[id]"), el => {
                let i = 0;
                if (idMap.has(el.id)) {
                    i = idMap.get(el.id);
                } else if (document.getElementById(el.id)) {
                    i = 1;
                    while (document.getElementById(`${el.id}-${2 * i}`)) {
                        i = 2 * i;
                    }
                    while (document.getElementById(`${el.id}-${i}`)) {
                        i += 1;
                    }
                }
                if (i !== 0) {
                    const oldHref = `#${el.id}`;
                    const newHref = `#${el.id}-${i}`;
                    el.id = `${el.id}-${i}`;
                    onEachLazy(template.content.querySelectorAll("a[href]"), link => {
                        if (link.getAttribute("href") === oldHref) {
                            link.href = newHref;
                        }
                    });
                }
                idMap.set(el.id, i + 1);
            });
            const templateAssocItems = template.content.querySelectorAll("section.tymethod, " +
                "section.method, section.associatedtype, section.associatedconstant");
            if (isTrait) {
                const li = document.createElement("li");
                const a = document.createElement("a");
                // @ts-expect-error
                a.href = `#${template.content.querySelector(".impl").id}`;
                a.textContent = traitName;
                li.appendChild(a);
                // @ts-expect-error
                sidebarTraitList.append(li);
            } else {
                onEachLazy(templateAssocItems, item => {
                    let block = hasClass(item, "associatedtype") ? associatedTypes : (
                        hasClass(item, "associatedconstant") ? associatedConstants : (
                        methods));
                    if (!block) {
                        const blockTitle = hasClass(item, "associatedtype") ? "Associated Types" : (
                            hasClass(item, "associatedconstant") ? "Associated Constants" : (
                            "Methods"));
                        const blockClass = hasClass(item, "associatedtype") ? "associatedtype" : (
                            hasClass(item, "associatedconstant") ? "associatedconstant" : (
                            "method"));
                        const blockHeader = document.createElement("h3");
                        const blockLink = document.createElement("a");
                        blockLink.href = "#implementations";
                        blockLink.innerText = blockTitle;
                        blockHeader.appendChild(blockLink);
                        block = document.createElement("ul");
                        block.className = `block ${blockClass}`;
                        const insertionReference = methods || sidebarTraitList;
                        if (insertionReference) {
                            const insertionReferenceH = insertionReference.previousElementSibling;
                            // @ts-expect-error
                            sidebarSection.insertBefore(blockHeader, insertionReferenceH);
                            // @ts-expect-error
                            sidebarSection.insertBefore(block, insertionReferenceH);
                        } else {
                            // @ts-expect-error
                            sidebarSection.appendChild(blockHeader);
                            // @ts-expect-error
                            sidebarSection.appendChild(block);
                        }
                        if (hasClass(item, "associatedtype")) {
                            associatedTypes = block;
                        } else if (hasClass(item, "associatedconstant")) {
                            associatedConstants = block;
                        } else {
                            methods = block;
                        }
                    }
                    const li = document.createElement("li");
                    const a = document.createElement("a");
                    a.innerText = item.id.split("-")[0].split(".")[1];
                    a.href = `#${item.id}`;
                    li.appendChild(a);
                    block.appendChild(li);
                });
            }
            outputList.appendChild(template.content);
        }

        for (const list of [methods, associatedTypes, associatedConstants, sidebarTraitList]) {
            if (!list) {
                continue;
            }
            const newChildren = Array.prototype.slice.call(list.children);
            newChildren.sort((a, b) => {
                const aI = a.innerText;
                const bI = b.innerText;
                return aI < bI ? -1 :
                    aI > bI ? 1 :
                    0;
            });
            list.replaceChildren(...newChildren);
        }
    };
    if (window.pending_type_impls) {
        window.register_type_impls(window.pending_type_impls);
    }

    function addSidebarCrates() {
        // @ts-expect-error
        if (!window.ALL_CRATES) {
            return;
        }
        const sidebarElems = document.getElementById("rustdoc-modnav");
        if (!sidebarElems) {
            return;
        }
        // Draw a convenient sidebar of known crates if we have a listing
        const h3 = document.createElement("h3");
        h3.innerHTML = "Crates";
        const ul = document.createElement("ul");
        ul.className = "block crate";

        // @ts-expect-error
        for (const crate of window.ALL_CRATES) {
            const link = document.createElement("a");
            link.href = window.rootPath + crate + "/index.html";
            link.textContent = crate;

            const li = document.createElement("li");
            if (window.rootPath !== "./" && crate === window.currentCrate) {
                li.className = "current";
            }
            li.appendChild(link);
            ul.appendChild(li);
        }
        sidebarElems.appendChild(h3);
        sidebarElems.appendChild(ul);
    }

    function expandAllDocs() {
        const innerToggle = document.getElementById(toggleAllDocsId);
        removeClass(innerToggle, "will-expand");
        onEachLazy(document.getElementsByClassName("toggle"), e => {
            if (!hasClass(e, "type-contents-toggle") && !hasClass(e, "more-examples-toggle")) {
                e.open = true;
            }
        });
        // @ts-expect-error
        innerToggle.children[0].innerText = "Summary";
    }

    /**
     * @param {boolean} collapseImpls - also collapse impl blocks if set to true
     */
    function collapseAllDocs(collapseImpls) {
        const innerToggle = document.getElementById(toggleAllDocsId);
        addClass(innerToggle, "will-expand");
        onEachLazy(document.getElementsByClassName("toggle"), e => {
            if ((collapseImpls || e.parentNode.id !== "implementations-list") ||
                (!hasClass(e, "implementors-toggle") &&
                 !hasClass(e, "type-contents-toggle"))
            ) {
                e.open = false;
            }
        });
        // @ts-expect-error
        innerToggle.children[0].innerText = "Show all";
    }

    /**
     * @param {MouseEvent=} ev
     */
    function toggleAllDocs(ev) {
        const innerToggle = document.getElementById(toggleAllDocsId);
        if (!innerToggle) {
            return;
        }
        if (hasClass(innerToggle, "will-expand")) {
            expandAllDocs();
        } else {
            collapseAllDocs(ev !== undefined && ev.shiftKey);
        }
    }

    (function() {
        const toggles = document.getElementById(toggleAllDocsId);
        if (toggles) {
            toggles.onclick = toggleAllDocs;
        }

        const hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true";
        const hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true";
        const hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false";

        // @ts-expect-error
        function setImplementorsTogglesOpen(id, open) {
            const list = document.getElementById(id);
            if (list !== null) {
                onEachLazy(list.getElementsByClassName("implementors-toggle"), e => {
                    e.open = open;
                });
            }
        }

        if (hideImplementations) {
            setImplementorsTogglesOpen("trait-implementations-list", false);
            setImplementorsTogglesOpen("blanket-implementations-list", false);
        }

        onEachLazy(document.getElementsByClassName("toggle"), e => {
            if (!hideLargeItemContents && hasClass(e, "type-contents-toggle")) {
                e.open = true;
            }
            if (hideMethodDocs && hasClass(e, "method-toggle")) {
                e.open = false;
            }

        });
    }());

    window.rustdoc_add_line_numbers_to_examples = () => {
        // @ts-expect-error
        function generateLine(nb) {
            return `<span data-nosnippet>${nb}</span>`;
        }

        onEachLazy(document.querySelectorAll(
            ".rustdoc:not(.src) :not(.scraped-example) > .example-wrap > pre > code",
        ), code => {
            if (hasClass(code.parentElement.parentElement, "hide-lines")) {
                removeClass(code.parentElement.parentElement, "hide-lines");
                return;
            }
            const lines = code.innerHTML.split("\n");
            const digits = (lines.length + "").length;
            // @ts-expect-error
            code.innerHTML = lines.map((line, index) => generateLine(index + 1) + line).join("\n");
            addClass(code.parentElement.parentElement, `digits-${digits}`);
        });
    };

    window.rustdoc_remove_line_numbers_from_examples = () => {
        onEachLazy(
            document.querySelectorAll(".rustdoc:not(.src) :not(.scraped-example) > .example-wrap"),
            x => addClass(x, "hide-lines"),
        );
    };

    if (getSettingValue("line-numbers") === "true") {
        window.rustdoc_add_line_numbers_to_examples();
    }

    function showSidebar() {
        window.hideAllModals(false);
        const sidebar = document.getElementsByClassName("sidebar")[0];
        addClass(sidebar, "shown");
    }

    function hideSidebar() {
        const sidebar = document.getElementsByClassName("sidebar")[0];
        removeClass(sidebar, "shown");
    }

    window.addEventListener("resize", () => {
        if (window.CURRENT_TOOLTIP_ELEMENT) {
            // As a workaround to the behavior of `contains: layout` used in doc togglers,
            // tooltip popovers are positioned using javascript.
            //
            // This means when the window is resized, we need to redo the layout.
            const base = window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;
            const force_visible = base.TOOLTIP_FORCE_VISIBLE;
            hideTooltip(false);
            if (force_visible) {
                showTooltip(base);
                base.TOOLTIP_FORCE_VISIBLE = true;
            }
        }
    });

    const mainElem = document.getElementById(MAIN_ID);
    if (mainElem) {
        mainElem.addEventListener("click", hideSidebar);
    }

    onEachLazy(document.querySelectorAll("a[href^='#']"), el => {
        // For clicks on internal links (<A> tags with a hash property), we expand the section we're
        // jumping to *before* jumping there. We can't do this in onHashChange, because it changes
        // the height of the document so we wind up scrolled to the wrong place.
        el.addEventListener("click", () => {
            expandSection(el.hash.slice(1));
            hideSidebar();
        });
    });

    onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"), el => {
        // @ts-expect-error
        // Clicking on the summary's contents should not collapse it,
        // but links within should still fire.
        el.addEventListener("click", e => {
            if (!e.target.matches("summary, a, a *")) {
                e.preventDefault();
            }
        });
    });

    /**
     * Show a tooltip immediately.
     *
     * @param {HTMLElement} e - The tooltip's anchor point. The DOM is consulted to figure
     *                          out what the tooltip should contain, and where it should be
     *                          positioned.
     */
    function showTooltip(e) {
        const notable_ty = e.getAttribute("data-notable-ty");
        if (!window.NOTABLE_TRAITS && notable_ty) {
            const data = document.getElementById("notable-traits-data");
            if (data) {
                window.NOTABLE_TRAITS = JSON.parse(data.innerText);
            } else {
                throw new Error("showTooltip() called with notable without any notable traits!");
            }
        }
        // Make this function idempotent. If the tooltip is already shown, avoid doing extra work
        // and leave it alone.
        if (window.CURRENT_TOOLTIP_ELEMENT && window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE === e) {
            clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
            return;
        }
        window.hideAllModals(false);
        // use Object.assign to make sure the object has the correct type
        // with all of the correct fields before it is assigned to a variable,
        // as typescript has no way to change the type of a variable once it is initialized.
        const wrapper = Object.assign(document.createElement("div"), {TOOLTIP_BASE: e});
        if (notable_ty) {
            wrapper.innerHTML = "<div class=\"content\">" +
                // @ts-expect-error
                window.NOTABLE_TRAITS[notable_ty] + "</div>";
        } else {
            // Replace any `title` attribute with `data-title` to avoid double tooltips.
            const ttl = e.getAttribute("title");
            if (ttl !== null) {
                e.setAttribute("data-title", ttl);
                e.removeAttribute("title");
            }
            const dttl = e.getAttribute("data-title");
            if (dttl !== null) {
                const titleContent = document.createElement("div");
                titleContent.className = "content";
                titleContent.appendChild(document.createTextNode(dttl));
                wrapper.appendChild(titleContent);
            }
        }
        wrapper.className = "tooltip popover";
        const focusCatcher = document.createElement("div");
        focusCatcher.setAttribute("tabindex", "0");
        // @ts-expect-error
        focusCatcher.onfocus = hideTooltip;
        wrapper.appendChild(focusCatcher);
        const pos = e.getBoundingClientRect();
        // 5px overlap so that the mouse can easily travel from place to place
        wrapper.style.top = (pos.top + window.scrollY + pos.height) + "px";
        // @ts-expect-error
        wrapper.style.left = 0;
        wrapper.style.right = "auto";
        wrapper.style.visibility = "hidden";
        document.body.appendChild(wrapper);
        const wrapperPos = wrapper.getBoundingClientRect();
        // offset so that the arrow points at the center of the "(i)"
        const finalPos = pos.left + window.scrollX - wrapperPos.width + 24;
        if (finalPos > 0) {
            wrapper.style.left = finalPos + "px";
        } else {
            wrapper.style.setProperty(
                "--popover-arrow-offset",
                (wrapperPos.right - pos.right + 4) + "px",
            );
        }
        wrapper.style.visibility = "";
        window.CURRENT_TOOLTIP_ELEMENT = wrapper;
        clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
        wrapper.onpointerenter = ev => {
            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
            if (ev.pointerType !== "mouse") {
                return;
            }
            clearTooltipHoverTimeout(e);
        };
        wrapper.onpointerleave = ev => {
            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
            if (ev.pointerType !== "mouse" || !(ev.relatedTarget instanceof HTMLElement)) {
                return;
            }
            if (!e.TOOLTIP_FORCE_VISIBLE && !e.contains(ev.relatedTarget)) {
                // See "Tooltip pointer leave gesture" below.
                setTooltipHoverTimeout(e, false);
                addClass(wrapper, "fade-out");
            }
        };
    }

    /**
     * Show or hide the tooltip after a timeout. If a timeout was already set before this function
     * was called, that timeout gets cleared. If the tooltip is already in the requested state,
     * this function will still clear any pending timeout, but otherwise do nothing.
     *
     * @param {HTMLElement} element - The tooltip's anchor point. The DOM is consulted to figure
     *                                out what the tooltip should contain, and where it should be
     *                                positioned.
     * @param {boolean}    show    - If true, the tooltip will be made visible. If false, it will
     *                               be hidden.
     */
    function setTooltipHoverTimeout(element, show) {
        clearTooltipHoverTimeout(element);
        if (!show && !window.CURRENT_TOOLTIP_ELEMENT) {
            // To "hide" an already hidden element, just cancel its timeout.
            return;
        }
        if (show && window.CURRENT_TOOLTIP_ELEMENT) {
            // To "show" an already visible element, just cancel its timeout.
            return;
        }
        if (window.CURRENT_TOOLTIP_ELEMENT &&
            window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE !== element) {
            // Don't do anything if another tooltip is already visible.
            return;
        }
        element.TOOLTIP_HOVER_TIMEOUT = setTimeout(() => {
            if (show) {
                showTooltip(element);
            } else if (!element.TOOLTIP_FORCE_VISIBLE) {
                hideTooltip(false);
            }
        }, show ? window.RUSTDOC_TOOLTIP_HOVER_MS : window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS);
    }

    /**
     * If a show/hide timeout was set by `setTooltipHoverTimeout`, cancel it. If none exists,
     * do nothing.
     *
     * @param {HTMLElement} element - The tooltip's anchor point,
     *                                as passed to `setTooltipHoverTimeout`.
     */
    function clearTooltipHoverTimeout(element) {
        if (element.TOOLTIP_HOVER_TIMEOUT !== undefined) {
            removeClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
            clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);
            delete element.TOOLTIP_HOVER_TIMEOUT;
        }
    }

    /**
     * @param {Event & { relatedTarget: Node }} event
     */
    function tooltipBlurHandler(event) {
        if (window.CURRENT_TOOLTIP_ELEMENT &&
            !window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement) &&
            !window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget) &&
            !window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement) &&
            !window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)
        ) {
            // Work around a difference in the focus behaviour between Firefox, Chrome, and Safari.
            // When I click the button on an already-opened tooltip popover, Safari
            // hides the popover and then immediately shows it again, while everyone else hides it
            // and it stays hidden.
            //
            // To work around this, make sure the click finishes being dispatched before
            // hiding the popover. Since `hideTooltip()` is idempotent, this makes Safari behave
            // consistently with the other two.
            setTimeout(() => hideTooltip(false), 0);
        }
    }

    /**
     * Hide the current tooltip immediately.
     *
     * @param {boolean} focus - If set to `true`, move keyboard focus to the tooltip anchor point.
     *                          If set to `false`, leave keyboard focus alone.
     */
    function hideTooltip(focus) {
        if (window.CURRENT_TOOLTIP_ELEMENT) {
            if (window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE) {
                if (focus) {
                    window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus();
                }
                window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE = false;
            }
            document.body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);
            clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
            window.CURRENT_TOOLTIP_ELEMENT = undefined;
        }
    }

    onEachLazy(document.getElementsByClassName("tooltip"), e => {
        e.onclick = () => {
            e.TOOLTIP_FORCE_VISIBLE = e.TOOLTIP_FORCE_VISIBLE ? false : true;
            if (window.CURRENT_TOOLTIP_ELEMENT && !e.TOOLTIP_FORCE_VISIBLE) {
                hideTooltip(true);
            } else {
                showTooltip(e);
                // @ts-expect-error
                window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex", "0");
                // @ts-expect-error
                window.CURRENT_TOOLTIP_ELEMENT.focus();
                // @ts-expect-error
                window.CURRENT_TOOLTIP_ELEMENT.onblur = tooltipBlurHandler;
            }
            return false;
        };
        // @ts-expect-error
        e.onpointerenter = ev => {
            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
            if (ev.pointerType !== "mouse") {
                return;
            }
            setTooltipHoverTimeout(e, true);
        };
        // @ts-expect-error
        e.onpointermove = ev => {
            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
            if (ev.pointerType !== "mouse") {
                return;
            }
            setTooltipHoverTimeout(e, true);
        };
        // @ts-expect-error
        e.onpointerleave = ev => {
            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
            if (ev.pointerType !== "mouse") {
                return;
            }
            if (!e.TOOLTIP_FORCE_VISIBLE && window.CURRENT_TOOLTIP_ELEMENT &&
                !window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)) {
                // Tooltip pointer leave gesture:
                //
                // Designing a good hover microinteraction is a matter of guessing user
                // intent from what are, literally, vague gestures. In this case, guessing if
                // hovering in or out of the tooltip base is intentional or not.
                //
                // To figure this out, a few different techniques are used:
                //
                // * When the mouse pointer enters a tooltip anchor point, its hitbox is grown
                //   on the bottom, where the popover is/will appear. Search "hover tunnel" in
                //   rustdoc.css for the implementation.
                // * There's a delay when the mouse pointer enters the popover base anchor, in
                //   case the mouse pointer was just passing through and the user didn't want
                //   to open it.
                // * Similarly, a delay is added when exiting the anchor, or the popover
                //   itself, before hiding it.
                // * A fade-out animation is layered onto the pointer exit delay to immediately
                //   inform the user that they successfully dismissed the popover, while still
                //   providing a way for them to cancel it if it was a mistake and they still
                //   wanted to interact with it.
                // * No animation is used for revealing it, because we don't want people to try
                //   to interact with an element while it's in the middle of fading in: either
                //   they're allowed to interact with it while it's fading in, meaning it can't
                //   serve as mistake-proofing for the popover, or they can't, but
                //   they might try and be frustrated.
                //
                // See also:
                // * https://www.nngroup.com/articles/timing-exposing-content/
                // * https://www.nngroup.com/articles/tooltip-guidelines/
                // * https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
                setTooltipHoverTimeout(e, false);
                addClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
            }
        };
    });

    const sidebar_menu_toggle = document.getElementsByClassName("sidebar-menu-toggle")[0];
    if (sidebar_menu_toggle) {
        sidebar_menu_toggle.addEventListener("click", () => {
            const sidebar = document.getElementsByClassName("sidebar")[0];
            // @ts-expect-error
            if (!hasClass(sidebar, "shown")) {
                showSidebar();
            } else {
                hideSidebar();
            }
        });
    }

    // @ts-expect-error
    function helpBlurHandler(event) {
        const isInPopover = onEachLazy(
            document.querySelectorAll(".settings-menu, .help-menu"),
            menu => {
                return menu.contains(document.activeElement) || menu.contains(event.relatedTarget);
            },
        );
        if (!isInPopover) {
            window.hidePopoverMenus();
        }
    }

    function buildHelpMenu() {
        const book_info = document.createElement("span");
        const drloChannel = `https://doc.rust-lang.org/${getVar("channel")}`;
        book_info.className = "top";
        book_info.innerHTML = `You can find more information in \
<a href="${drloChannel}/rustdoc/">the rustdoc book</a>.`;

        const shortcuts = [
            ["?", "Show this help dialog"],
            ["S / /", "Focus the search field"],
            ["↑", "Move up in search results"],
            ["↓", "Move down in search results"],
            ["← / →", "Switch result tab (when results focused)"],
            ["&#9166;", "Go to active search result"],
            ["+ / =", "Expand all sections"],
            ["-", "Collapse all sections"],
            // for the sake of brevity, we don't say "inherit impl blocks",
            // although that would be more correct,
            // since trait impl blocks are collapsed by -
            ["_", "Collapse all sections, including impl blocks"],
        ].map(x => "<dt>" +
            x[0].split(" ")
                .map((y, index) => ((index & 1) === 0 ? "<kbd>" + y + "</kbd>" : " " + y + " "))
                .join("") + "</dt><dd>" + x[1] + "</dd>").join("");
        const div_shortcuts = document.createElement("div");
        addClass(div_shortcuts, "shortcuts");
        div_shortcuts.innerHTML = "<h2>Keyboard Shortcuts</h2><dl>" + shortcuts + "</dl></div>";

        const infos = [
            `For a full list of all search features, take a look \
             <a href="${drloChannel}/rustdoc/read-documentation/search.html">here</a>.`,
            "Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to \
             restrict the search to a given item kind.",
            "Accepted kinds are: <code>fn</code>, <code>mod</code>, <code>struct</code>, \
             <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \
             and <code>const</code>.",
            "Search functions by type signature (e.g., <code>vec -&gt; usize</code> or \
             <code>-&gt; vec</code> or <code>String, enum:Cow -&gt; bool</code>)",
            "You can look for items with an exact name by putting double quotes around \
             your request: <code>\"string\"</code>",
             `Look for functions that accept or return \
              <a href="${drloChannel}/std/primitive.slice.html">slices</a> and \
              <a href="${drloChannel}/std/primitive.array.html">arrays</a> by writing square \
              brackets (e.g., <code>-&gt; [u8]</code> or <code>[] -&gt; Option</code>)`,
            "Look for items inside another one by searching for a path: <code>vec::Vec</code>",
        ].map(x => "<p>" + x + "</p>").join("");
        const div_infos = document.createElement("div");
        addClass(div_infos, "infos");
        div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos;

        const rustdoc_version = document.createElement("span");
        rustdoc_version.className = "bottom";
        const rustdoc_version_code = document.createElement("code");
        rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version");
        rustdoc_version.appendChild(rustdoc_version_code);

        const container = document.createElement("div");
        if (!isHelpPage) {
            container.className = "popover content";
        }
        container.id = "help";

        const side_by_side = document.createElement("div");
        side_by_side.className = "side-by-side";
        side_by_side.appendChild(div_shortcuts);
        side_by_side.appendChild(div_infos);

        container.appendChild(book_info);
        container.appendChild(side_by_side);
        container.appendChild(rustdoc_version);

        if (isHelpPage) {
            const help_section = document.createElement("section");
            help_section.appendChild(container);
            nonnull(document.getElementById("main-content")).appendChild(help_section);
        } else {
            onEachLazy(document.getElementsByClassName("help-menu"), menu => {
                if (menu.offsetWidth !== 0) {
                    menu.appendChild(container);
                    container.onblur = helpBlurHandler;
                    menu.onblur = helpBlurHandler;
                    menu.children[0].onblur = helpBlurHandler;
                    return true;
                }
            });
        }

        return container;
    }

    /**
     * Hide popover menus, clickable tooltips, and the sidebar (if applicable).
     *
     * Pass `true` to reset focus for tooltip popovers.
     */
    window.hideAllModals = switchFocus => {
        hideSidebar();
        window.hidePopoverMenus();
        hideTooltip(switchFocus);
    };

    /**
     * Hide all the popover menus.
     */
    window.hidePopoverMenus = () => {
        onEachLazy(document.querySelectorAll(".settings-menu .popover"), elem => {
            elem.style.display = "none";
        });
        onEachLazy(document.querySelectorAll(".help-menu .popover"), elem => {
            elem.parentElement.removeChild(elem);
        });
    };

    /**
     * Show the help popup menu.
     */
    function showHelp() {
        window.hideAllModals(false);
        // Prevent `blur` events from being dispatched as a result of closing
        // other modals.
        onEachLazy(document.querySelectorAll(".help-menu a"), menu => {
            if (menu.offsetWidth !== 0) {
                menu.focus();
                return true;
            }
        });
        buildHelpMenu();
    }

    if (isHelpPage) {
        buildHelpMenu();
    } else {
        onEachLazy(document.querySelectorAll(".help-menu > a"), helpLink => {
            helpLink.addEventListener(
                "click",
                /** @param {MouseEvent} event */
                event => {
                    // By default, have help button open docs in a popover.
                    // If user clicks with a moderator, though, use default browser behavior,
                    // probably opening in a new window or tab.
                    if (event.ctrlKey ||
                        event.altKey ||
                        event.metaKey) {
                        return;
                    }
                    event.preventDefault();
                    if (document.getElementById("help")) {
                        window.hidePopoverMenus();
                    } else {
                        showHelp();
                    }
                },
            );
        });
    }

    addSidebarItems();
    addSidebarCrates();
    onHashChange(null);
    window.addEventListener("hashchange", onHashChange);
    window.searchState.setup();
}());

// Hide, show, and resize the sidebar
//
// The body class and CSS variable are initially set up in storage.js,
// but in this file, we implement:
//
//   * the show sidebar button, which appears if the sidebar is hidden
//     and, by clicking on it, will bring it back
//   * the sidebar resize handle, which appears only on large viewports
//     with a [fine precision pointer] to allow the user to change
//     the size of the sidebar
//
// [fine precision pointer]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
(function() {
    // 100 is the size of the logo
    // don't let the sidebar get smaller than that, or it'll get squished
    const SIDEBAR_MIN = 100;
    // Don't let the sidebar get bigger than this
    const SIDEBAR_MAX = 500;
    // Don't let the body (including the gutter) get smaller than this
    //
    // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
    // Acceptable values for BODY_MIN are constrained by the mobile breakpoint
    // (which is the minimum size of the whole page where the sidebar exists)
    // and the default sidebar width:
    //
    //     BODY_MIN <= RUSTDOC_MOBILE_BREAKPOINT - DEFAULT_SIDEBAR_WIDTH
    //
    // At the time of this writing, the DEFAULT_SIDEBAR_WIDTH on src pages is
    // 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be
    // at most 400px. Otherwise, it would start out at the default size, then
    // grabbing the resize handle would suddenly cause it to jank to
    // its constraint-generated maximum.
    const RUSTDOC_MOBILE_BREAKPOINT = 700;
    const BODY_MIN = 400;
    // At half-way past the minimum size, vanish the sidebar entirely
    const SIDEBAR_VANISH_THRESHOLD = SIDEBAR_MIN / 2;

    // Toolbar button to show the sidebar.
    //
    // On small, "mobile-sized" viewports, it's not persistent and it
    // can only be activated by going into Settings and hiding the nav bar.
    // On larger, "desktop-sized" viewports (though that includes many
    // tablets), it's fixed-position, appears in the left side margin,
    // and it can be activated by resizing the sidebar into nothing.
    let sidebarButton = document.getElementById("sidebar-button");
    const body = document.querySelector(".main-heading");
    if (!sidebarButton && body) {
        sidebarButton = document.createElement("div");
        sidebarButton.id = "sidebar-button";
        const path = `${window.rootPath}${window.currentCrate}/all.html`;
        sidebarButton.innerHTML = `<a href="${path}" title="show sidebar"></a>`;
        body.insertBefore(sidebarButton, body.firstChild);
    }
    if (sidebarButton) {
        sidebarButton.addEventListener("click", e => {
            removeClass(document.documentElement, "hide-sidebar");
            updateLocalStorage("hide-sidebar", "false");
            if (window.rustdocToggleSrcSidebar) {
                window.rustdocToggleSrcSidebar();
            }
            e.preventDefault();
        });
    }

    /**
     * Pointer capture.
     *
     * Resizing is a single-pointer gesture. Any secondary pointer is ignored
     *
     * @type {null|number}
     */
    let currentPointerId = null;

    /**
     * "Desired" sidebar size.
     *
     * This is stashed here for window resizing. If the sidebar gets
     * shrunk to maintain BODY_MIN, and then the user grows the window again,
     * it gets the sidebar to restore its size.
     *
     * @type {null|number}
     */
    let desiredSidebarSize = null;

    /**
     * Sidebar resize debouncer.
     *
     * The sidebar itself is resized instantly, but the body HTML can be too
     * big for that, causing reflow jank. To reduce this, we queue up a separate
     * animation frame and throttle it.
     *
     * @type {false|ReturnType<typeof setTimeout>}
     */
    let pendingSidebarResizingFrame = false;

    /** @type {HTMLElement|null} */
    const resizer = document.querySelector(".sidebar-resizer");
    /** @type {HTMLElement|null} */
    const sidebar = document.querySelector(".sidebar");
    // If this page has no sidebar at all, bail out.
    if (!resizer || !sidebar) {
        return;
    }

    // src page and docs page use different variables, because the contents of
    // the sidebar are so different that it's reasonable to thing the user
    // would want them to have different sizes
    const isSrcPage = hasClass(document.body, "src");

    // Call this function to hide the sidebar when using the resize handle
    //
    // This function also nulls out the sidebar width CSS variable and setting,
    // causing it to return to its default. This does not happen if you do it
    // from settings.js, which uses a separate function. It's done here because
    // the minimum sidebar size is rather uncomfortable, and it must pass
    // through that size when using the shrink-to-nothing gesture.
    const hideSidebar = function() {
        if (isSrcPage) {
            window.rustdocCloseSourceSidebar();
            updateLocalStorage("src-sidebar-width", null);
            // [RUSTDOCIMPL] CSS variable fast path
            //
            // The sidebar width variable is attached to the <html> element by
            // storage.js, because the sidebar and resizer don't exist yet.
            // But the resize code, in `resize()`, sets the property on the
            // sidebar and resizer elements (which are the only elements that
            // use the variable) to avoid recalculating CSS on the entire
            // document on every frame.
            //
            // So, to clear it, we need to clear all three.
            document.documentElement.style.removeProperty("--src-sidebar-width");
            sidebar.style.removeProperty("--src-sidebar-width");
            resizer.style.removeProperty("--src-sidebar-width");
        } else {
            addClass(document.documentElement, "hide-sidebar");
            updateLocalStorage("hide-sidebar", "true");
            updateLocalStorage("desktop-sidebar-width", null);
            document.documentElement.style.removeProperty("--desktop-sidebar-width");
            sidebar.style.removeProperty("--desktop-sidebar-width");
            resizer.style.removeProperty("--desktop-sidebar-width");
        }
    };

    // Call this function to show the sidebar from the resize handle.
    // On docs pages, this can only happen if the user has grabbed the resize
    // handle, shrunk the sidebar down to nothing, and then pulls back into
    // the visible range without releasing it. You can, however, grab the
    // resize handle on a source page with the sidebar closed, because it
    // remains visible all the time on there.
    const showSidebar = function() {
        if (isSrcPage) {
            window.rustdocShowSourceSidebar();
        } else {
            removeClass(document.documentElement, "hide-sidebar");
            updateLocalStorage("hide-sidebar", "false");
        }
    };

    /**
     * Call this to set the correct CSS variable and setting.
     * This function doesn't enforce size constraints. Do that before calling it!
     *
     * @param {number} size - CSS px width of the sidebar.
     */
    const changeSidebarSize = function(size) {
        if (isSrcPage) {
            updateLocalStorage("src-sidebar-width", size.toString());
            // [RUSTDOCIMPL] CSS variable fast path
            //
            // While this property is set on the HTML element at load time,
            // because the sidebar isn't actually loaded yet,
            // we scope this update to the sidebar to avoid hitting a slow
            // path in WebKit.
            sidebar.style.setProperty("--src-sidebar-width", size + "px");
            resizer.style.setProperty("--src-sidebar-width", size + "px");
        } else {
            updateLocalStorage("desktop-sidebar-width", size.toString());
            sidebar.style.setProperty("--desktop-sidebar-width", size + "px");
            resizer.style.setProperty("--desktop-sidebar-width", size + "px");
        }
    };

    // Check if the sidebar is hidden. Since src pages and doc pages have
    // different settings, this function has to check that.
    const isSidebarHidden = function() {
        return isSrcPage ?
            !hasClass(document.documentElement, "src-sidebar-expanded") :
            hasClass(document.documentElement, "hide-sidebar");
    };

    /**
     * Respond to the resize handle event.
     * This function enforces size constraints, and implements the
     * shrink-to-nothing gesture based on thresholds defined above.
     *
     * @param {PointerEvent} e
     */
    const resize = function(e) {
        if (currentPointerId === null || currentPointerId !== e.pointerId) {
            return;
        }
        e.preventDefault();
        const pos = e.clientX - 3;
        if (pos < SIDEBAR_VANISH_THRESHOLD) {
            hideSidebar();
        } else if (pos >= SIDEBAR_MIN) {
            if (isSidebarHidden()) {
                showSidebar();
            }
            // don't let the sidebar get wider than SIDEBAR_MAX, or the body narrower
            // than BODY_MIN
            const constrainedPos = Math.min(pos, window.innerWidth - BODY_MIN, SIDEBAR_MAX);
            changeSidebarSize(constrainedPos);
            desiredSidebarSize = constrainedPos;
            if (pendingSidebarResizingFrame !== false) {
                clearTimeout(pendingSidebarResizingFrame);
            }
            pendingSidebarResizingFrame = setTimeout(() => {
                if (currentPointerId === null || pendingSidebarResizingFrame === false) {
                    return;
                }
                pendingSidebarResizingFrame = false;
                document.documentElement.style.setProperty(
                    "--resizing-sidebar-width",
                    desiredSidebarSize + "px",
                );
            }, 100);
        }
    };
    // Respond to the window resize event.
    window.addEventListener("resize", () => {
        if (window.innerWidth < RUSTDOC_MOBILE_BREAKPOINT) {
            return;
        }
        stopResize();
        if (desiredSidebarSize !== null && desiredSidebarSize >= (window.innerWidth - BODY_MIN)) {
            changeSidebarSize(window.innerWidth - BODY_MIN);
        } else if (desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN) {
            changeSidebarSize(desiredSidebarSize);
        }
    });

    /**
     * @param {PointerEvent=} e
     */
    const stopResize = function(e) {
        if (currentPointerId === null) {
            return;
        }
        if (e) {
            e.preventDefault();
        }
        desiredSidebarSize = sidebar.getBoundingClientRect().width;
        removeClass(resizer, "active");
        window.removeEventListener("pointermove", resize, false);
        window.removeEventListener("pointerup", stopResize, false);
        removeClass(document.documentElement, "sidebar-resizing");
        document.documentElement.style.removeProperty( "--resizing-sidebar-width");
        if (resizer.releasePointerCapture) {
            resizer.releasePointerCapture(currentPointerId);
            currentPointerId = null;
        }
    };

    /**
     * @param {PointerEvent} e
     */
    const initResize = function(e) {
        if (currentPointerId !== null || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
            return;
        }
        if (resizer.setPointerCapture) {
            resizer.setPointerCapture(e.pointerId);
            if (!resizer.hasPointerCapture(e.pointerId)) {
                // unable to capture pointer; something else has it
                // on iOS, this usually means you long-clicked a link instead
                resizer.releasePointerCapture(e.pointerId);
                return;
            }
            currentPointerId = e.pointerId;
        }
        window.hideAllModals(false);
        e.preventDefault();
        window.addEventListener("pointermove", resize, false);
        window.addEventListener("pointercancel", stopResize, false);
        window.addEventListener("pointerup", stopResize, false);
        addClass(resizer, "active");
        addClass(document.documentElement, "sidebar-resizing");
        const pos = e.clientX - sidebar.offsetLeft - 3;
        document.documentElement.style.setProperty( "--resizing-sidebar-width", pos + "px");
        desiredSidebarSize = null;
    };
    resizer.addEventListener("pointerdown", initResize, false);
}());

// This section handles the copy button that appears next to the path breadcrumbs
// and the copy buttons on the code examples.
(function() {
    // Common functions to copy buttons.
    /**
     * @param {string|null} content
     */
    function copyContentToClipboard(content) {
        if (content === null) {
            return;
        }
        const el = document.createElement("textarea");
        el.value = content;
        el.setAttribute("readonly", "");
        // To not make it appear on the screen.
        el.style.position = "absolute";
        el.style.left = "-9999px";

        document.body.appendChild(el);
        el.select();
        document.execCommand("copy");
        document.body.removeChild(el);
    }

    /**
     * @param {HTMLElement & {reset_button_timeout?: ReturnType<typeof setTimeout>}} button
     */
    function copyButtonAnimation(button) {
        button.classList.add("clicked");

        if (button.reset_button_timeout !== undefined) {
            clearTimeout(button.reset_button_timeout);
        }

        button.reset_button_timeout = setTimeout(() => {
            button.reset_button_timeout = undefined;
            button.classList.remove("clicked");
        }, 1000);
    }

    // Copy button that appears next to the path breadcrumbs.
    const but = document.getElementById("copy-path");
    if (!but) {
        return;
    }
    but.onclick = () => {
        // Most page titles are '<Item> in <path::to::module> - Rust', except
        // modules (which don't have the first part) and keywords/primitives
        // (which don't have a module path)
        const titleElement = document.querySelector("title");
        const title = titleElement && titleElement.textContent ?
                      titleElement.textContent.replace(" - Rust", "") : "";
        const [item, module] = title.split(" in ");
        const path = [item];
        if (module !== undefined) {
            path.unshift(module);
        }

        copyContentToClipboard(path.join("::"));
        copyButtonAnimation(but);
    };

    /**
     * Copy buttons on code examples.
     * @param {HTMLElement|null} codeElem
     */
    function copyCode(codeElem) {
        if (!codeElem) {
            // Should never happen, but the world is a dark and dangerous place.
            return;
        }
        copyContentToClipboard(codeElem.textContent);
    }

    /**
     * @param {UIEvent} event
     * @returns {HTMLElement|null}
     */
    function getExampleWrap(event) {
        const target = event.target;
        if (target instanceof HTMLElement) {
            /** @type {HTMLElement|null} */
            let elem = target;
            while (elem !== null && !hasClass(elem, "example-wrap")) {
                if (elem === document.body ||
                    elem.tagName === "A" ||
                    elem.tagName === "BUTTON" ||
                    hasClass(elem, "docblock")
                ) {
                    return null;
                }
                elem = elem.parentElement;
            }
            return elem;
        } else {
            return null;
        }
    }

    /**
     * @param {UIEvent} event
     */
    function addCopyButton(event) {
        const elem = getExampleWrap(event);
        if (elem === null) {
            return;
        }
        // Since the button will be added, no need to keep this listener around.
        elem.removeEventListener("mouseover", addCopyButton);

        const parent = document.createElement("div");
        parent.className = "button-holder";

        const runButton = elem.querySelector(".test-arrow");
        if (runButton !== null) {
            // If there is a run button, we move it into the same div.
            parent.appendChild(runButton);
        }
        elem.appendChild(parent);
        const copyButton = document.createElement("button");
        copyButton.className = "copy-button";
        copyButton.title = "Copy code to clipboard";
        copyButton.addEventListener("click", () => {
            copyCode(elem.querySelector("pre > code"));
            copyButtonAnimation(copyButton);
        });
        parent.appendChild(copyButton);

        if (!elem.parentElement || !elem.parentElement.classList.contains("scraped-example") ||
            !window.updateScrapedExample) {
            return;
        }
        const scrapedWrapped = elem.parentElement;
        window.updateScrapedExample(scrapedWrapped, parent);
    }

    /**
     * @param {UIEvent} event
     */
    function showHideCodeExampleButtons(event) {
        const elem = getExampleWrap(event);
        if (elem === null) {
            return;
        }
        let buttons = elem.querySelector(".button-holder");
        if (buttons === null) {
            // On mobile, you can't hover an element so buttons need to be created on click
            // if they're not already there.
            addCopyButton(event);
            buttons = elem.querySelector(".button-holder");
            if (buttons === null) {
                return;
            }
        }
        buttons.classList.toggle("keep-visible");
    }

    onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => {
        elem.addEventListener("mouseover", addCopyButton);
        elem.addEventListener("click", showHideCodeExampleButtons);
    });
}());


// Workaround for browser-specific bugs when copying code snippets.
//
// * In Firefox, copying text that includes elements with `user-select: none`
//   inserts extra blank lines.
//   - Firefox issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1273836
//   - Rust issue: https://github.com/rust-lang/rust/issues/141464
//
// * In Chromium-based browsers, `document.getSelection()` includes elements
//   with `user-select: none`, causing unwanted line numbers to be copied.
//   - Chromium issue: https://issues.chromium.org/issues/446539520
//   - Rust issue: https://github.com/rust-lang/rust/issues/146816
(function() {
    document.body.addEventListener("copy", event => {
        let target = nonnull(event.target);
        let isInsideCode = false;
        while (target && target !== document.body) {
            // @ts-expect-error
            if (target.tagName === "CODE") {
                isInsideCode = true;
                break;
            }
            // @ts-expect-error
            target = target.parentElement;
        }
        if (!isInsideCode) {
            return;
        }
        const selection = nonnull(document.getSelection());
        const text = Array.from({ length: selection.rangeCount }, (_, i) => {
            const fragment = selection.getRangeAt(i).cloneContents();
            fragment.querySelectorAll("[data-nosnippet]").forEach(el => el.remove());
            return fragment.textContent;
        }).join("");
        nonnull(event.clipboardData).setData("text/plain", text);
        event.preventDefault();
    });
}());
