text: /**
   * Copyright (c) 2017-present, Facebook, Inc.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   */
  
  const CWD = process.cwd();
  
  const React = require('react');
  const fs = require('fs');
  const classNames = require('classnames');
  const siteConfig = require(CWD + '/siteConfig.js');
  const translation = require('../../server/translation.js');
  const env = require('../../server/env.js');
  
  const translate = require('../../server/translate.js').translate;
  const setLanguage = require('../../server/translate.js').setLanguage;
  
  const readMetadata = require('../../server/readMetadata.js');
  readMetadata.generateMetadataDocs();
  const Metadata = require('../metadata.js');
  
  // language dropdown nav item for when translations are enabled
  class LanguageDropDown extends React.Component {
    render() {
      setLanguage(this.props.language || 'en');
      let helpTranslateString = translate(
        'Help Translate|recruit community translators for your project'
      );
      // add all enabled languages to dropdown
      const enabledLanguages = env.translation
        .enabledLanguages()
        .filter(lang => lang.tag !== this.props.language)
        .map(lang => (
          <li key={lang.tag}>
            <a href={siteConfig.baseUrl + lang.tag}>{lang.name}</a>
          </li>
        ));
      // if no languages are enabled besides English, return null
      if (enabledLanguages.length < 1) {
        return null;
      }
  
      // Get the current language full name for display in the header nav
      const currentLanguage = env.translation
        .enabledLanguages()
        .filter(lang => lang.tag === this.props.language)
        .map(lang => lang.name);
  
      // add Crowdin project recruiting link
      if (siteConfig.translationRecruitingLink) {
        enabledLanguages.push(
          <li key="recruiting">
            <a
              href={siteConfig.translationRecruitingLink}
              target="_blank"
              rel="noreferrer noopener">
              {helpTranslateString}
            </a>
          </li>
        );
      }
  
      return (
        <span>
          <li key="languages">
            <a id="languages-menu" href="#">
              <img
                className="languages-icon"
                src={this.props.baseUrl + 'img/language.svg'}
              />
              {currentLanguage}
            </a>
            <div id="languages-dropdown" className="hide">
              <ul id="languages-dropdown-items">{enabledLanguages}</ul>
            </div>
          </li>
          <script
            dangerouslySetInnerHTML={{
              __html: `
          const languagesMenuItem = document.getElementById("languages-menu");
          const languagesDropDown = document.getElementById("languages-dropdown");
          languagesMenuItem.addEventListener("click", function(){
            if(languagesDropDown.className == "hide") {
              languagesDropDown.className = "visible";
            } else {
              languagesDropDown.className = "hide";
            }
          });
        `,
            }}
          />
        </span>
      );
    }
  }
  
  // header navbar used by all pages generated with docusaurus
  class HeaderNav extends React.Component {
    constructor() {
      super();
      this.state = {
        slideoutActive: false,
      };
    }
    // function to generate each header link, used with each object in siteConfig.headerLinks
    makeLinks(link) {
      let href;
      let docItemActive = false;
      let docGroupActive = false;
      if (link.search && this.props.config.algolia) {
        // return algolia search bar
        return (
          <li className="navSearchWrapper reactNavSearchWrapper" key="search">
            <input
              id="search_input_react"
              type="text"
              placeholder="Search"
              title="Search"
            />
          </li>
        );
      } else if (link.languages) {
        if (
          env.translation.enabled &&
          env.translation.enabledLanguages().length > 1
        ) {
          return (
            <LanguageDropDown
              baseUrl={this.props.baseUrl}
              language={this.props.language}
              key="languagedropdown"
            />
          );
        } else {
          return null;
        }
      } else if (link.doc) {
        // set link to document with current page's language/version
        const langPart = env.translation.enabled
          ? (this.props.language || 'en') + '-'
          : '';
        const versionPart =
          env.versioning.enabled && this.props.version !== 'next'
            ? 'version-' +
              (this.props.version || env.versioning.latestVersion) +
              '-'
            : '';
        const id = langPart + versionPart + link.doc;
        if (!Metadata[id]) {
          let errorStr =
            "Processing the following `doc` field in `headerLinks` within `siteConfig.js`: '" +
            link.doc +
            "'";
          if (id === link.doc) {
            errorStr +=
              ' It looks like there is no document with that id that exists in your docs directory. Please double check the spelling of your `doc` field and the `id` fields of your docs.';
          } else {
            errorStr +=
              '. Check the spelling of your `doc` field. If that seems sane, and a document in your docs folder exists with that `id` value, \nthen this is likely a bug in Docusaurus.' +
              ' Docusaurus thinks one or both of translations (currently set to: ' +
              env.translation.enabled +
              ') or versioning (currently set to: ' +
              env.versioning.enabled +
              ") is enabled when maybe they should not be. \nThus my internal id for this doc is: '" +
              id +
              "'. Please file an issue for this possible bug on GitHub.";
          }
          throw new Error(errorStr);
        }
        href = this.props.config.baseUrl + Metadata[id].permalink;
  
        const {id: currentID, sidebar} = this.props.current;
        docItemActive = currentID && currentID === id;
        docGroupActive = sidebar && sidebar === Metadata[id].sidebar;
      } else if (link.page) {
        // set link to page with current page's language if appropriate
        const language = this.props.language || '';
        if (fs.existsSync(CWD + '/pages/en/' + link.page + '.js')) {
          href =
            siteConfig.baseUrl +
            (language ? language + '/' : '') +
            link.page +
            '.html';
        } else {
          href = siteConfig.baseUrl + link.page + '.html';
        }
      } else if (link.href) {
        // set link to specified href
        href = link.href;
      } else if (link.blog) {
        // set link to blog url
        href = this.props.baseUrl + 'blog';
      }
      const itemClasses = classNames({
        siteNavGroupActive:
          (link.doc && docGroupActive) || (link.blog && this.props.current.blog),
        siteNavItemActive:
          docItemActive ||
          (link.blog && this.props.current.blogListing) ||
          (link.page && link.page === this.props.current.id),
      });
      return (
        <li key={link.label + 'page'} className={itemClasses}>
          <a href={href} target={link.external ? '_blank' : '_self'}>
            {translation[this.props.language]
              ? translation[this.props.language]['localized-strings'][link.label]
              : link.label}
          </a>
        </li>
      );
    }
  
    fetchVersions() {
      var versionsObj = {};
      const version = JSON.parse(fs.readFileSync(CWD + '/versions.json', 'utf8'));
      var versions = version.versions;
      Object.keys(versions).sort(function(a,b) {return b-a;}).forEach(vr => {
        versionsObj[vr] = versions[vr];
      })
      return versionsObj;
    }
  
    render() {
      const versionsLink =
        this.props.baseUrl +
        (env.translation.enabled
          ? this.props.language + '/versions.html'
          : 'versions.html');
      return (
        <div className="fixedHeaderContainer">
          <div className="headerWrapper wrapper">
            <header>
              <a
                href={
                  this.props.baseUrl +
                  (env.translation.enabled ? this.props.language : '')
                }>
                {siteConfig.headerIcon && (
                  <img
                  id="logo"
                    src={this.props.baseUrl + siteConfig.headerIcon}
                    alt={siteConfig.title}
                  />
                )}
                {siteConfig.headerIcon && (
                  <img
                    className="logo-text"
                    src={this.props.baseUrl + siteConfig.headerText}
                    alt={siteConfig.title}
                  />
                )}
                {!this.props.config.disableHeaderTitle && (
                  <h2 className="headerTitle">{this.props.title}</h2>
                )}
              </a>
              {env.versioning.enabled && (
                  <div className="dropdown">
                    <span className="ver-link">{Object.keys(this.fetchVersions())[0]}</span>
                    <span className="ver-link-span">
                    <i className="arrow down"></i>
                    </span>
                    <div className="dropdown-menu" id="versions-list" aria-labelledby="dropdownMenuButton">
                      {Object.keys(this.fetchVersions()).map((version, i) => {
                        return <a className="dropdown-item" id={`${i}`} href={this.fetchVersions()[`${version}`][1]}>{version}</a>;
                      })}
                    </div>
                 </div>
              )}
              {this.renderResponsiveNav()}
            </header>
          </div>
        </div>
      );
    }
  
    renderResponsiveNav() {
      const headerLinks = this.props.config.headerLinks;
      // add language drop down to end if location not specified
      let languages = false;
      headerLinks.forEach(link => {
        if (link.languages) {
          languages = true;
        }
      });
      if (!languages) {
        headerLinks.push({languages: true});
      }
      let search = false;
      headerLinks.forEach(link => {
        if (
          link.doc &&
          !fs.existsSync(CWD + '/../' + readMetadata.getDocsPath() + '/')
        ) {
          throw new Error(
            "You have 'doc' in your headerLinks, but no '" +
              readMetadata.getDocsPath() +
              "' folder exists one level up from " +
              "'website' folder. Did you run `docusaurus-init` or `npm run examples`? If so, " +
              "make sure you rename 'docs-examples-from-docusaurus' to 'docs'."
          );
        }
        if (link.blog && !fs.existsSync(CWD + '/blog/')) {
          throw new Error(
            "You have 'blog' in your headerLinks, but no 'blog' folder exists in your " +
              "'website' folder. Did you run `docusaurus-init` or `npm run examples`? If so, " +
              "make sure you rename 'blog-examples-from-docusaurus' to 'blog'."
          );
        }
        if (link.page && !fs.existsSync(CWD + '/pages/')) {
          throw new Error(
            "You have 'page' in your headerLinks, but no 'pages' folder exists in your " +
              "'website' folder."
          );
        }
        // We will add search bar to end if location not specified
        if (link.search) {
          search = true;
        }
      });
      if (!search && this.props.config.algolia) {
        headerLinks.push({search: true});
      }
      return (
        <div className="navigationWrapper navigationSlider">
          <nav className="slidingNav">
            <ul className="nav-site nav-site-internal">
              {headerLinks.map(this.makeLinks, this)}
            </ul>
          </nav>
        </div>
      );
    }
  }
  
  HeaderNav.defaultProps = {
    current: {},
  };
  
  module.exports = HeaderNav;
  