diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 31179fd867..92069d9afd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,7 +81,7 @@ jobs: - name: Gradle Build run: | chmod +x gradlew - ./gradlew photon-server:build photon-lib:build -x check --max-workers 2 + ./gradlew build -x check --max-workers 2 - name: Gradle Tests run: ./gradlew testHeadless -i --max-workers 1 --stacktrace - name: Gradle Coverage diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000000..d8d11b60ed --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,92 @@ +name: Documentation + +on: + push: + # For now, run on all commits to master + branches: [ master ] + # and also all tags starting with v + tags: + - 'v*' + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-client: + name: "PhotonClient Build" + defaults: + run: + working-directory: photon-client + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18 + - name: Install Dependencies + run: npm ci + - name: Build Production Client + run: npm run build-demo + - uses: actions/upload-artifact@v4 + with: + name: built-client + path: photon-client/dist/ + + run_docs: + runs-on: "ubuntu-22.04" + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Fetch tags + run: git fetch --tags --force + - name: Install Java 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + + - name: Build javadocs/doxygen + run: | + chmod +x gradlew + ./gradlew docs:generateJavaDocs docs:doxygen + + - uses: actions/upload-artifact@v4 + with: + name: built-docs + path: docs/build/docs + + release: + needs: [build-client, run_docs] + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-22.04 + steps: + + # Download literally every single artifact. + - uses: actions/download-artifact@v4 + + - run: find . + + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire repository + path: '.' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index d1cff5e77e..542ac3f2a4 100644 --- a/README.md +++ b/README.md @@ -92,3 +92,10 @@ Our meeting notes can be found in the wiki section of this repository. * [2020 Meeting Notes](https://github.com/PhotonVision/photonvision/wiki/2020-Meeting-Notes) * [2021 Meeting Notes](https://github.com/PhotonVision/photonvision/wiki/2021-Meeting-Notes) + +## Documentation + +- Our main documentation page: [docs.photonvision.org](https://docs.photonvision.org) +- Photon UI demo: [demo.photonvision.org](https://demo.photonvision.org) (or [manual link](https://photonvision.github.io/photonvision/built-client/)) +- Javadocs: [javadocs.photonvision.org](https://javadocs.photonvision.org) (or [manual link](https://photonvision.github.io/photonvision/built-docs/javadoc/)) +- C++ Doxygen [cppdocs.photonvision.org](https://cppdocs.photonvision.org) (or [manual link](https://photonvision.github.io/photonvision/built-docs/doxygen/html/)) diff --git a/docs/build.gradle b/docs/build.gradle new file mode 100644 index 0000000000..f6ce182199 --- /dev/null +++ b/docs/build.gradle @@ -0,0 +1,287 @@ +// From allwpilib/docs. Licensed under the WPILib BSD License + +plugins { + id 'java' + id "org.ysb33r.doxygen" version "0.7.0" +} + + +evaluationDependsOn ':photon-targeting' +evaluationDependsOn ':photon-core' +evaluationDependsOn ':photon-server' +evaluationDependsOn ':photon-lib' + + +def baseArtifactIdCpp = 'documentation' +def artifactGroupIdCpp = 'org.photonvision.wpilibc' +def zipBaseNameCpp = '_GROUP_org.photonvision_cpp_ID_documentation_CLS' + +def baseArtifactIdJava = 'documentation' +def artifactGroupIdJava = 'org.photonvision.wpilibj' +def zipBaseNameJava = '_GROUP_org.photonvision_java_ID_documentation_CLS' + +def outputsFolder = file("$project.buildDir/outputs") + +def cppProjectZips = [] +def cppIncludeRoots = [] + +cppProjectZips.add(project(':photon-lib').cppHeadersZip) +cppProjectZips.add(project(':photon-targeting').cppHeadersZip) + +doxygen { + // Doxygen binaries are only provided for x86_64 platforms + // Other platforms will need to provide doxygen via their system + // See below maven and https://doxygen.nl/download.html for provided binaries + + String arch = System.getProperty("os.arch"); + if (arch.equals("x86_64") || arch.equals("amd64")) { + executables { + doxygen version : '1.9.4', + baseURI : 'https://frcmaven.wpi.edu/artifactory/generic-release-mirror/doxygen' + } + } +} + +doxygen { + generate_html true + html_extra_stylesheet 'theme.css' + + cppProjectZips.each { + dependsOn it + source it.source + it.ext.includeDirs.each { + cppIncludeRoots.add(it.absolutePath) + } + } + cppIncludeRoots << '../ntcore/build/generated/main/native/include/' + + if (project.hasProperty('docWarningsAsErrors')) { + // Eigen + exclude 'Eigen/**' + exclude 'unsupported/**' + + // LLVM + exclude 'wpi/AlignOf.h' + exclude 'wpi/Casting.h' + exclude 'wpi/Chrono.h' + exclude 'wpi/Compiler.h' + exclude 'wpi/ConvertUTF.h' + exclude 'wpi/DenseMap.h' + exclude 'wpi/DenseMapInfo.h' + exclude 'wpi/Endian.h' + exclude 'wpi/EpochTracker.h' + exclude 'wpi/Errc.h' + exclude 'wpi/Errno.h' + exclude 'wpi/ErrorHandling.h' + exclude 'wpi/bit.h' + exclude 'wpi/fs.h' + exclude 'wpi/FunctionExtras.h' + exclude 'wpi/function_ref.h' + exclude 'wpi/Hashing.h' + exclude 'wpi/iterator.h' + exclude 'wpi/iterator_range.h' + exclude 'wpi/ManagedStatic.h' + exclude 'wpi/MapVector.h' + exclude 'wpi/MathExtras.h' + exclude 'wpi/MemAlloc.h' + exclude 'wpi/PointerIntPair.h' + exclude 'wpi/PointerLikeTypeTraits.h' + exclude 'wpi/PointerUnion.h' + exclude 'wpi/raw_os_ostream.h' + exclude 'wpi/raw_ostream.h' + exclude 'wpi/SmallPtrSet.h' + exclude 'wpi/SmallSet.h' + exclude 'wpi/SmallString.h' + exclude 'wpi/SmallVector.h' + exclude 'wpi/StringExtras.h' + exclude 'wpi/StringMap.h' + exclude 'wpi/SwapByteOrder.h' + exclude 'wpi/type_traits.h' + exclude 'wpi/VersionTuple.h' + exclude 'wpi/WindowsError.h' + + // fmtlib + exclude 'fmt/**' + + // libuv + exclude 'uv.h' + exclude 'uv/**' + exclude 'wpinet/uv/**' + + // json + exclude 'wpi/adl_serializer.h' + exclude 'wpi/byte_container_with_subtype.h' + exclude 'wpi/detail/**' + exclude 'wpi/json.h' + exclude 'wpi/json_fwd.h' + exclude 'wpi/ordered_map.h' + exclude 'wpi/thirdparty/**' + + // memory + exclude 'wpi/memory/**' + + // mpack + exclude 'wpi/mpack.h' + + // units + exclude 'units/**' + } + + //TODO: building memory docs causes search to break + exclude 'wpi/memory/**' + + exclude '*.pb.h' + + // Save space by excluding protobuf and eigen + exclude 'Eigen/**' + exclude 'google/protobuf/**' + + aliases 'effects=\\par Effects:^^', + 'notes=\\par Notes:^^', + 'requires=\\par Requires:^^', + 'requiredbe=\\par Required Behavior:^^', + 'concept{2}=\2', + 'defaultbe=\\par Default Behavior:^^' + case_sense_names false + extension_mapping 'inc=C++', 'no_extension=C++' + extract_all true + extract_static true + file_patterns '*' + full_path_names true + generate_html true + generate_latex false + generate_treeview true + html_extra_stylesheet 'theme.css' + html_timestamp true + javadoc_autobrief true + project_name 'PhotonVision C++' + project_logo '../wpiutil/src/main/native/resources/wpilib-128.png' + project_number pubVersion + quiet true + recursive true + strip_code_comments false + strip_from_inc_path cppIncludeRoots as String[] + strip_from_path cppIncludeRoots as String[] + use_mathjax true + warnings false + warn_if_incomplete_doc true + warn_if_undocumented false + warn_no_paramdoc true + + //enable doxygen preprocessor expansion of WPI_DEPRECATED to fix MotorController docs + enable_preprocessing true + macro_expansion true + expand_only_predef true + predefined "WPI_DEPRECATED(x)=[[deprecated(x)]]\"\\\n" + + "\"__cplusplus\"\\\n" + + "\"HAL_ENUM(name)=enum name : int32_t" + + if (project.hasProperty('docWarningsAsErrors')) { + warn_as_error 'FAIL_ON_WARNINGS' + } +} + +tasks.register("zipCppDocs", Zip) { + archiveBaseName = zipBaseNameCpp + destinationDirectory = outputsFolder + dependsOn doxygen + from ("$buildDir/docs/doxygen/html") + into '/' +} + +// Java +configurations { + javaSource { + transitive false + } +} + +ext { + sharedCvConfigs = [:] + staticCvConfigs = [:] + useJava = true + useCpp = false + skipDev = true + useDocumentation = true +} + +task generateJavaDocs(type: Javadoc) { + def exportedProjects = [ + ':photon-core', + ':photon-server', + ':photon-targeting', + ':photon-lib' + ] + + source exportedProjects.collect { project(it).sourceSets.main.allJava } + classpath = files(exportedProjects.collect { project(it).sourceSets.main.compileClasspath }) + dependsOn project(':photon-core').writeCurrentVersion + + options.links("https://docs.oracle.com/en/java/javase/17/docs/api/") + options.addStringOption("tag", "pre:a:Pre-Condition") + options.addBooleanOption("Xdoclint:html,missing,reference,syntax", true) + options.addBooleanOption('html5', true) + failOnError = true + + title = "PhotonVision $pubVersion" + ext.entryPoint = "$destinationDir/index.html" + + if (JavaVersion.current().isJava8Compatible() && project.hasProperty('docWarningsAsErrors')) { + // Treat javadoc warnings as errors. + // + // The second argument '-quiet' is a hack. The one parameter + // addStringOption() doesn't work, so we add '-quiet', which is added + // anyway by gradle. See https://github.com/gradle/gradle/issues/2354. + // + // See JDK-8200363 (https://bugs.openjdk.java.net/browse/JDK-8200363) + // for information about the nonstandard -Xwerror option. JDK 15+ has + // -Werror. + options.addStringOption('Xwerror', '-quiet') + } + + if (JavaVersion.current().isJava11Compatible()) { + if (!JavaVersion.current().isJava12Compatible()) { + options.addBooleanOption('-no-module-directories', true) + } + doLast { + // This is a work-around for https://bugs.openjdk.java.net/browse/JDK-8211194. Can be removed once that issue is fixed on JDK's side + // Since JDK 11, package-list is missing from javadoc output files and superseded by element-list file, but a lot of external tools still need it + // Here we generate this file manually + new File(destinationDir, 'package-list').text = new File(destinationDir, 'element-list').text + } + } +} + +tasks.register("zipJavaDocs", Zip) { + archiveBaseName = zipBaseNameJava + destinationDirectory = outputsFolder + dependsOn generateJavaDocs + from ("$buildDir/docs/javadoc") + into '/' +} + +tasks.register("zipDocs") { + dependsOn zipCppDocs + dependsOn zipJavaDocs +} + +apply plugin: 'maven-publish' + +publishing { + publications { + java(MavenPublication) { + artifact zipJavaDocs + + artifactId = "${baseArtifactIdJava}" + groupId artifactGroupIdJava + version pubVersion + } + cpp(MavenPublication) { + artifact zipCppDocs + + artifactId = "${baseArtifactIdCpp}" + groupId artifactGroupIdCpp + version pubVersion + } + } +} diff --git a/docs/theme.css b/docs/theme.css new file mode 100644 index 0000000000..2bca53a108 --- /dev/null +++ b/docs/theme.css @@ -0,0 +1,1697 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +html { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #1779c4; + --primary-dark-color: #00559f; + --primary-light-color: #7aabd6; + --primary-lighter-color: #cae1f1; + --primary-lightest-color: #e9f1f8; + + /* page base colors */ + --page-background-color: white; + --page-foreground-color: #2c3e50; + --page-secondary-foreground-color: #67727e; + + /* color for all separators on the website: hr, borders, ... */ + --separator-color: #dedede; + + /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ + --border-radius-large: 8px; + --border-radius-small: 4px; + --border-radius-medium: 6px; + + /* default spacings. Most compontest reference these values for spacing, to provide uniform spacing on the page. */ + --spacing-small: 5px; + --spacing-medium: 10px; + --spacing-large: 16px; + + /* default box shadow used for raising an element above the normal content. Used in dropdowns, Searchresult, ... */ + --box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.1); + + --odd-color: rgba(0, 0, 0, 0.03); + + /* font-families. will affect all text on the website + * font-family: the normal font for text, headlines, menus + * font-family-monospace: used for preformatted text in memtitle, code, fragments + */ + --font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + --font-family-monospace: source-code-pro, Menlo, Monaco, Consolas, + Courier New, monospace; + + /* font sizes */ + --page-font-size: 15.6px; + --navigation-font-size: 14.4px; + --code-font-size: 14.4px; /* affects code, fragment */ + --title-font-size: 22px; + + /* content text properties. These only affect the page content, not the navigation or any other ui elements */ + --content-line-height: 27px; + /* The content is centered and constraint in it's width. To make the content fill the whole page, set the variable to auto.*/ + --content-maxwidth: 1000px; + + /* colors for various content boxes: @warning, @note, @deprecated @bug */ + --warning-color: #fca49b; + --warning-color-dark: #b61825; + --warning-color-darker: #75070f; + --note-color: rgba(255, 229, 100, 0.3); + --note-color-dark: #c39900; + --note-color-darker: #8d7400; + --deprecated-color: rgb(214, 216, 224); + --deprecated-color-dark: #5b6269; + --deprecated-color-darker: #43454a; + --bug-color: rgb(246, 208, 178); + --bug-color-dark: #a53a00; + --bug-color-darker: #5b1d00; + --invariant-color: #b7f8d0; + --invariant-color-dark: #00ba44; + --invariant-color-darker: #008622; + + /* blockquote colors */ + --blockquote-background: #f5f5f5; + --blockquote-foreground: #727272; + + /* table colors */ + --tablehead-background: #f1f1f1; + --tablehead-foreground: var(--page-foreground-color); + + /* menu-display: block | none + * Visibility of the top navigation on screens >= 768px. On smaller screen the menu is always visible. + * `GENERATE_TREEVIEW` MUST be enabled! + */ + --menu-display: block; + + --menu-focus-foreground: var(--page-background-color); + --menu-focus-background: var(--primary-color); + --menu-selected-background: rgba(0, 0, 0, 0.05); + + --header-background: var(--page-background-color); + --header-foreground: var(--page-foreground-color); + + /* searchbar colors */ + --searchbar-background: var(--side-nav-background); + --searchbar-foreground: var(--page-foreground-color); + + /* searchbar size + * (`searchbar-width` is only applied on screens >= 768px. + * on smaller screens the searchbar will always fill the entire screen width) */ + --searchbar-height: 33px; + --searchbar-width: 210px; + + /* code block colors */ + --code-background: #f5f5f5; + --code-foreground: var(--page-foreground-color); + + /* fragment colors */ + --fragment-background: #282c34; + --fragment-foreground: #ffffff; + --fragment-keyword: #cc99cd; + --fragment-keywordtype: #ab99cd; + --fragment-keywordflow: #e08000; + --fragment-token: #7ec699; + --fragment-comment: #999999; + --fragment-link: #98c0e3; + --fragment-preprocessor: #65cabe; + --fragment-linenumber-color: #cccccc; + --fragment-linenumber-background: #35393c; + --fragment-linenumber-border: #1f1f1f; + --fragment-lineheight: 20px; + + /* sidebar navigation (treeview) colors */ + --side-nav-background: #fbfbfb; + --side-nav-foreground: var(--page-foreground-color); + --side-nav-arrow-opacity: 0; + --side-nav-arrow-hover-opacity: 0.9; + + /* height of an item in any tree / collapsible table */ + --tree-item-height: 30px; + + --darkmode-toggle-button-icon: "☀️"; +} + +@media screen and (max-width: 767px) { + html { + --page-font-size: 16px; + --navigation-font-size: 16px; + --code-font-size: 15px; /* affects code, fragment */ + --title-font-size: 22px; + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.35); + + --odd-color: rgba(0, 0, 0, 0.1); + + --menu-selected-background: rgba(0, 0, 0, 0.4); + + --page-background-color: #1c1d1f; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #fff6df; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: "🌛"; + } +} + +/* dark mode variables are defined twice, to support both the dark-mode without and with doxygen-awesome-darkmode-toggle.js */ +html.dark-mode { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.35); + + --odd-color: rgba(0, 0, 0, 0.1); + + --menu-selected-background: rgba(0, 0, 0, 0.4); + + --page-background-color: #1c1d1f; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #fff6df; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: "🌛"; +} + +body { + color: var(--page-foreground-color); + background-color: var(--page-background-color); + font-size: var(--page-font-size); +} + +body, +table, +div, +p, +dl, +#nav-tree .label, +.title, +.sm-dox a, +.sm-dox a:hover, +.sm-dox a:focus, +#projectname, +.SelectItem, +#MSearchField, +.navpath li.navelem a, +.navpath li.navelem a:hover { + font-family: var(--font-family); +} + +h1, +h2, +h3, +h4, +h5 { + margin-top: 0.9em; + font-weight: 600; + line-height: initial; +} + +p, +div, +table, +dl { + font-size: var(--page-font-size); +} + +a:link, +a:visited, +a:hover, +a:focus, +a:active { + color: var(--primary-color) !important; + font-weight: 500; +} + +/* + Title and top navigation + */ + +#top { + background: var(--header-background); + border-bottom: 1px solid var(--separator-color); +} + +@media screen and (min-width: 768px) { + #top { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + } +} + +#main-nav { + flex-grow: 5; + padding: var(--spacing-small) var(--spacing-medium); +} + +#titlearea { + width: auto; + padding: var(--spacing-medium) var(--spacing-large); + background: none; + color: var(--header-foreground); + border-bottom: none; +} + +@media screen and (max-width: 767px) { + #titlearea { + padding-bottom: var(--spacing-small); + } +} + +#titlearea table tbody tr { + height: auto !important; +} + +#projectname { + font-size: var(--title-font-size); + font-weight: 600; +} + +#projectnumber { + font-family: inherit; + font-size: 60%; +} + +#projectbrief { + font-family: inherit; + font-size: 80%; +} + +#projectlogo { + vertical-align: middle; +} + +#projectlogo img { + max-height: calc(var(--title-font-size) * 2); + margin-right: var(--spacing-small); +} + +.sm-dox, +.tabs, +.tabs2, +.tabs3 { + background: none; + padding: 0; +} + +.tabs, +.tabs2, +.tabs3 { + border-bottom: 1px solid var(--separator-color); + margin-bottom: -1px; +} + +@media screen and (max-width: 767px) { + .sm-dox a span.sub-arrow { + background: var(--code-background); + } +} + +@media screen and (min-width: 768px) { + .sm-dox li, + .tablist li { + display: var(--menu-display); + } + + .sm-dox a span.sub-arrow { + border-color: var(--header-foreground) transparent transparent + transparent; + } + + .sm-dox a:hover span.sub-arrow { + border-color: var(--menu-focus-foreground) transparent transparent + transparent; + } + + .sm-dox ul a span.sub-arrow { + border-color: transparent transparent transparent + var(--page-foreground-color); + } + + .sm-dox ul a:hover span.sub-arrow { + border-color: transparent transparent transparent + var(--menu-focus-foreground); + } +} + +.sm-dox ul { + background: var(--page-background-color); + box-shadow: var(--box-shadow); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium) !important; + padding: var(--spacing-small); + animation: ease-out 150ms slideInMenu; +} + +@keyframes slideInMenu { + from { + opacity: 0; + transform: translate(0px, -2px); + } + + to { + opacity: 1; + transform: translate(0px, 0px); + } +} + +.sm-dox ul a { + color: var(--page-foreground-color) !important; + background: var(--page-background-color); + font-size: var(--navigation-font-size); +} + +.sm-dox > li > ul:after { + border-bottom-color: var(--page-background-color) !important; +} + +.sm-dox > li > ul:before { + border-bottom-color: var(--separator-color) !important; +} + +.sm-dox ul a:hover, +.sm-dox ul a:active, +.sm-dox ul a:focus { + font-size: var(--navigation-font-size) !important; + color: var(--menu-focus-foreground) !important; + text-shadow: none; + background-color: var(--menu-focus-background); + border-radius: var(--border-radius-small) !important; +} + +.sm-dox a, +.sm-dox a:focus, +.tablist li, +.tablist li a, +.tablist li.current a { + text-shadow: none; + background: transparent; + background-image: none !important; + color: var(--header-foreground) !important; + font-weight: normal; + font-size: var(--navigation-font-size); +} + +.sm-dox a:focus { + outline: auto; +} + +.sm-dox a:hover, +.sm-dox a:active, +.tablist li a:hover { + text-shadow: none; + font-weight: normal; + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; + border-radius: var(--border-radius-small) !important; + font-size: var(--navigation-font-size); +} + +.tablist li.current { + border-radius: var(--border-radius-small); + background: var(--menu-selected-background); +} + +.tablist li { + margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-small); +} + +.tablist a { + padding: 0 var(--spacing-large); +} + +/* + Search box + */ + +#MSearchBox { + height: var(--searchbar-height); + background: var(--searchbar-background); + border-radius: var(--searchbar-height); + border: 1px solid var(--separator-color); + overflow: hidden; + width: var(--searchbar-width); + position: relative; + box-shadow: none; + display: block; + margin-top: 0; +} + +.left #MSearchSelect { + left: 0; +} + +.tabs .left #MSearchSelect { + padding-left: 0; +} + +.tabs #MSearchBox { + position: absolute; + right: var(--spacing-medium); +} + +@media screen and (max-width: 767px) { + .tabs #MSearchBox { + position: relative; + right: 0; + margin-left: var(--spacing-medium); + margin-top: 0; + } +} + +#MSearchSelectWindow, +#MSearchResultsWindow { + z-index: 9999; +} + +#MSearchBox.MSearchBoxActive { + border-color: var(--primary-color); + box-shadow: inset 0 0 0 1px var(--primary-color); +} + +#main-menu > li:last-child { + margin-right: 0; +} + +@media screen and (max-width: 767px) { + #main-menu > li:last-child { + height: 50px; + } +} + +#MSearchField { + font-size: var(--navigation-font-size); + height: calc(var(--searchbar-height) - 2px); + background: transparent; + width: calc(var(--searchbar-width) - 64px); +} + +.MSearchBoxActive #MSearchField { + color: var(--searchbar-foreground); +} + +#MSearchSelect { + top: calc(calc(var(--searchbar-height) / 2) - 11px); +} + +.left #MSearchSelect { + padding-left: 8px; +} + +#MSearchBox span.left, +#MSearchBox span.right { + background: none; +} + +#MSearchBox span.right { + padding-top: calc(calc(var(--searchbar-height) / 2) - 12px); + position: absolute; + right: var(--spacing-small); +} + +.tabs #MSearchBox span.right { + top: calc(calc(var(--searchbar-height) / 2) - 12px); +} + +@keyframes slideInSearchResults { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } +} + +#MSearchResultsWindow { + left: auto !important; + right: var(--spacing-medium); + border-radius: var(--border-radius-large); + border: 1px solid var(--separator-color); + transform: translate(0, 20px); + box-shadow: var(--box-shadow); + animation: ease-out 280ms slideInSearchResults; + background: var(--page-background-color); +} + +iframe#MSearchResults { + margin: 4px; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) iframe#MSearchResults { + filter: invert() hue-rotate(180deg); + } +} + +html.dark-mode iframe#MSearchResults { + filter: invert() hue-rotate(180deg); +} + +#MSearchSelectWindow { + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + background: var(--page-background-color); +} + +#MSearchSelectWindow a.SelectItem { + font-size: var(--navigation-font-size); + line-height: var(--content-line-height); + margin: 0 var(--spacing-small); + border-radius: var(--border-radius-small); + color: var(--page-foreground-color) !important; + font-weight: normal; +} + +#MSearchSelectWindow a.SelectItem:hover { + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; +} + +@media screen and (max-width: 767px) { + #MSearchBox { + margin-top: var(--spacing-medium); + margin-bottom: var(--spacing-medium); + width: calc(100vw - 30px); + } + + #main-menu > li:last-child { + float: none !important; + } + + #MSearchField { + width: calc(100vw - 110px); + } + + @keyframes slideInSearchResultsMobile { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: var(--spacing-medium); + overflow: auto; + transform: translate(0, 20px); + animation: ease-out 280ms slideInSearchResultsMobile; + } +} + +/* + Tree view + */ + +#side-nav { + padding: 0 !important; + background: var(--side-nav-background); +} + +@media screen and (max-width: 767px) { + #side-nav { + display: none; + } + + #doc-content { + margin-left: 0 !important; + height: auto !important; + padding-bottom: calc(2 * var(--spacing-large)); + } +} + +#nav-tree { + background: transparent; +} + +#nav-tree .label { + font-size: var(--navigation-font-size); +} + +#nav-tree .item { + height: var(--tree-item-height); + line-height: var(--tree-item-height); +} + +#nav-sync { + top: 12px !important; + right: 12px; +} + +#nav-tree .selected { + text-shadow: none; + background-image: none; + background-color: transparent; + box-shadow: inset 4px 0 0 0 var(--primary-color); +} + +#nav-tree a { + color: var(--side-nav-foreground) !important; + font-weight: normal; +} + +#nav-tree a:focus { + outline-style: auto; +} + +#nav-tree .arrow { + opacity: var(--side-nav-arrow-opacity); +} + +.arrow { + color: inherit; + cursor: pointer; + font-size: 45%; + vertical-align: middle; + margin-right: 2px; + font-family: serif; + height: auto; + text-align: right; +} + +#nav-tree div.item:hover .arrow, +#nav-tree a:focus .arrow { + opacity: var(--side-nav-arrow-hover-opacity); +} + +#nav-tree .selected a { + color: var(--primary-color) !important; + font-weight: bolder; + font-weight: 600; +} + +.ui-resizable-e { + background: var(--separator-color); + width: 1px; +} + +/* + Contents + */ + +div.header { + border-bottom: 1px solid var(--separator-color); + background-color: var(--page-background-color); + background-image: none; +} + +div.contents, +div.header .title, +div.header .summary { + max-width: var(--content-maxwidth); +} + +div.contents, +div.header .title { + line-height: initial; + margin: calc(var(--spacing-medium) + 0.2em) auto var(--spacing-medium) auto; +} + +div.header .summary { + margin: var(--spacing-medium) auto 0 auto; +} + +div.headertitle { + padding: 0; +} + +div.header .title { + font-weight: 600; + font-size: 210%; + padding: var(--spacing-medium) var(--spacing-large); + word-break: break-word; +} + +div.header .summary { + width: auto; + display: block; + float: none; + padding: 0 var(--spacing-large); +} + +td.memSeparator { + border-color: var(--separator-color); +} + +.mdescLeft, +.mdescRight, +.memItemLeft, +.memItemRight, +.memTemplItemLeft, +.memTemplItemRight, +.memTemplParams { + background: var(--code-background); +} + +.mdescRight { + color: var(--page-secondary-foreground-color); +} + +span.mlabel { + background: var(--primary-color); + border: none; + padding: 4px 9px; + border-radius: 12px; + margin-right: var(--spacing-medium); +} + +span.mlabel:last-of-type { + margin-right: 2px; +} + +div.contents { + padding: 0 var(--spacing-large); +} + +div.contents p, +div.contents li { + line-height: var(--content-line-height); +} + +div.contents div.dyncontent { + margin: var(--spacing-medium) 0; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) div.contents div.dyncontent img, + html:not(.light-mode) div.contents center img, + html:not(.light-mode) div.contents table img, + html:not(.light-mode) div.contents div.dyncontent iframe, + html:not(.light-mode) div.contents center iframe, + html:not(.light-mode) div.contents table iframe { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode div.contents div.dyncontent img, +html.dark-mode div.contents center img, +html.dark-mode div.contents table img, +html.dark-mode div.contents div.dyncontent iframe, +html.dark-mode div.contents center iframe, +html.dark-mode div.contents table iframe { + filter: hue-rotate(180deg) invert(); +} + +h2.groupheader { + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color); +} + +blockquote { + padding: var(--spacing-small) var(--spacing-medium); + background: var(--blockquote-background); + color: var(--blockquote-foreground); + border-left: 2px solid var(--blockquote-foreground); + margin: 0; +} + +blockquote p { + margin: var(--spacing-small) 0 var(--spacing-medium) 0; +} +.paramname { + font-weight: 600; + color: var(--primary-dark-color); +} + +.glow { + text-shadow: 0 0 15px var(--primary-light-color) !important; +} + +.alphachar a { + color: var(--page-foreground-color); +} + +/* + Table of Contents + */ + +div.toc { + background-color: var(--side-nav-background); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + padding: 0 var(--spacing-large); + margin: 0 0 var(--spacing-medium) var(--spacing-medium); +} + +div.toc h3 { + color: var(--side-nav-foreground); + font-size: var(--navigation-font-size); + margin: var(--spacing-large) 0; +} + +div.toc li { + font-size: var(--navigation-font-size); + padding: 0; + background: none; +} + +div.toc li:before { + content: "↓"; + font-weight: 800; + font-family: var(--font-family); + margin-right: var(--spacing-small); + color: var(--side-nav-foreground); + opacity: 0.4; +} + +div.toc ul li.level1 { + margin: 0; +} + +div.toc ul li.level2, +div.toc ul li.level3 { + margin-top: 0; +} + +@media screen and (max-width: 767px) { + div.toc { + float: none; + width: auto; + margin: 0 0 var(--spacing-medium) 0; + } +} + +/* + Code & Fragments + */ + +code, +div.fragment, +pre.fragment { + border-radius: var(--border-radius-small); + border: none; + overflow: hidden; +} + +code { + display: inline; + background: var(--code-background); + color: var(--code-foreground); + padding: 2px 6px; + word-break: break-word; +} + +div.fragment, +pre.fragment { + margin: var(--spacing-medium) 0; + padding: 14px 16px; + background: var(--fragment-background); + color: var(--fragment-foreground); + overflow-x: auto; +} + +@media screen and (max-width: 767px) { + div.fragment, + pre.fragment { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .contents > div.fragment, + .textblock > div.fragment, + .textblock > pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + border-radius: 0; + } + + .textblock li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + } + + .memdoc li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + } + + .memdoc > div.fragment, + .memdoc > pre.fragment, + dl dd > div.fragment, + dl dd pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + border-radius: 0; + } +} + +code, +code a, +pre.fragment, +div.fragment, +div.fragment .line, +div.fragment span, +div.fragment .line a, +div.fragment .line span { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size) !important; +} + +div.line:after { + margin-right: var(--spacing-medium); +} + +div.fragment .line, +pre.fragment { + white-space: pre; + word-wrap: initial; + line-height: var(--fragment-lineheight); +} + +div.fragment span.keyword { + color: var(--fragment-keyword); +} + +div.fragment span.keywordtype { + color: var(--fragment-keywordtype); +} + +div.fragment span.keywordflow { + color: var(--fragment-keywordflow); +} + +div.fragment span.stringliteral { + color: var(--fragment-token); +} + +div.fragment span.comment { + color: var(--fragment-comment); +} + +div.fragment a.code { + color: var(--fragment-link) !important; +} + +div.fragment span.preprocessor { + color: var(--fragment-preprocessor); +} + +div.fragment span.lineno { + display: inline-block; + width: 27px; + border-right: none; + background: var(--fragment-linenumber-background); + color: var(--fragment-linenumber-color); +} + +div.fragment span.lineno a { + background: none; + color: var(--fragment-link) !important; +} + +div.fragment .line:first-child .lineno { + box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), + -999998px 0px 0 999999px var(--fragment-linenumber-border); +} + +/* + dl warning, attention, note, deprecated, bug, ... + */ + +dl.warning, +dl.attention, +dl.note, +dl.deprecated, +dl.bug, +dl.invariant, +dl.pre { + padding: var(--spacing-medium); + margin: var(--spacing-medium) 0; + color: var(--page-background-color); + overflow: hidden; + margin-left: 0; + border-radius: var(--border-radius-small); +} + +dl.section dd { + margin-bottom: 2px; +} + +dl.warning, +dl.attention { + background: var(--warning-color); + border-left: 8px solid var(--warning-color-dark); + color: var(--warning-color-darker); +} + +dl.warning dt, +dl.attention dt { + color: var(--warning-color-dark); +} + +dl.note { + background: var(--note-color); + border-left: 8px solid var(--note-color-dark); + color: var(--note-color-darker); +} + +dl.note dt { + color: var(--note-color-dark); +} + +dl.bug { + background: var(--bug-color); + border-left: 8px solid var(--bug-color-dark); + color: var(--bug-color-darker); +} + +dl.bug dt a { + color: var(--bug-color-dark) !important; +} + +dl.deprecated { + background: var(--deprecated-color); + border-left: 8px solid var(--deprecated-color-dark); + color: var(--deprecated-color-darker); +} + +dl.deprecated dt a { + color: var(--deprecated-color-dark) !important; +} + +dl.section dd, +dl.bug dd, +dl.deprecated dd { + margin-inline-start: 0px; +} + +dl.invariant, +dl.pre { + background: var(--invariant-color); + border-left: 8px solid var(--invariant-color-dark); + color: var(--invariant-color-darker); +} + +/* + memitem + */ + +div.memdoc, +div.memproto, +h2.memtitle { + box-shadow: none; + background-image: none; + border: none; +} + +div.memdoc { + padding: 0 var(--spacing-medium); + background: var(--page-background-color); +} + +h2.memtitle, +div.memitem { + border: 1px solid var(--separator-color); +} + +div.memproto, +h2.memtitle { + background: var(--code-background); + text-shadow: none; +} + +h2.memtitle { + font-weight: 500; + font-family: monospace, fixed; + border-bottom: none; + border-top-left-radius: var(--border-radius-medium); + border-top-right-radius: var(--border-radius-medium); + word-break: break-all; +} + +a:target + h2.memtitle, +a:target + h2.memtitle + div.memitem { + border-color: var(--primary-light-color); +} + +a:target + h2.memtitle { + box-shadow: -3px -3px 3px 0 var(--primary-lightest-color), + 3px -3px 3px 0 var(--primary-lightest-color); +} + +a:target + h2.memtitle + div.memitem { + box-shadow: 0 0 10px 0 var(--primary-lighter-color); +} + +div.memitem { + border-top-right-radius: var(--border-radius-medium); + border-bottom-right-radius: var(--border-radius-medium); + border-bottom-left-radius: var(--border-radius-medium); + overflow: hidden; + display: block !important; +} + +div.memdoc { + border-radius: 0; +} + +div.memproto { + border-radius: 0 var(--border-radius-small) 0 0; + overflow: auto; + border-bottom: 1px solid var(--separator-color); + padding: var(--spacing-medium); + margin-bottom: -1px; +} + +div.memtitle { + border-top-right-radius: var(--border-radius-medium); + border-top-left-radius: var(--border-radius-medium); +} + +div.memproto table.memname { + font-family: monospace, fixed; + color: var(--page-foreground-color); +} + +table.mlabels, +table.mlabels > tbody { + display: block; +} + +td.mlabels-left { + width: auto; +} + +table.mlabels > tbody > tr:first-child { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.memname, +.memitem span.mlabels { + margin: 0; +} + +/* + reflist + */ + +dl.reflist { + box-shadow: var(--box-shadow); + border-radius: var(--border-radius-medium); + border: 1px solid var(--separator-color); + overflow: hidden; + padding: 0; +} + +dl.reflist dt, +dl.reflist dd { + box-shadow: none; + text-shadow: none; + background-image: none; + border: none; + padding: 12px; +} + +dl.reflist dt { + font-weight: 500; + border-radius: 0; + background: var(--code-background); + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color); +} + +dl.reflist dd { + background: none; +} + +/* + Table + */ + +table.markdownTable, +table.fieldtable { + width: 100%; + border: 1px solid var(--separator-color); + margin: var(--spacing-medium) 0; +} + +table.fieldtable { + box-shadow: none; + border-radius: var(--border-radius-small); +} + +th.markdownTableHeadLeft, +th.markdownTableHeadRight, +th.markdownTableHeadCenter, +th.markdownTableHeadNone { + background: var(--tablehead-background); + color: var(--tablehead-foreground); + font-weight: 600; + font-size: var(--page-font-size); +} + +table.markdownTable td, +table.markdownTable th, +table.fieldtable dt { + border: 1px solid var(--separator-color); + padding: var(--spacing-small) var(--spacing-medium); +} + +table.fieldtable th { + font-size: var(--page-font-size); + font-weight: 600; + background-image: none; + background-color: var(--tablehead-background); + color: var(--tablehead-foreground); + border-bottom: 1px solid var(--separator-color); +} + +.fieldtable td.fieldtype, +.fieldtable td.fieldname { + border-bottom: 1px solid var(--separator-color); + border-right: 1px solid var(--separator-color); +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--separator-color); +} + +.memberdecls td.glow, +.fieldtable tr.glow { + background-color: var(--primary-light-color); + box-shadow: 0 0 15px var(--primary-lighter-color); +} + +table.memberdecls { + display: block; + overflow-x: auto; + overflow-y: hidden; +} + +/* + Horizontal Rule + */ + +hr { + margin-top: var(--spacing-large); + margin-bottom: var(--spacing-large); + border-top: 1px solid var(--separator-color); +} + +.contents hr { + box-shadow: var(--content-maxwidth) 0 0 0 var(--separator-color), + calc(0px - var(--content-maxwidth)) 0 0 0 var(--separator-color); +} + +.contents img { + max-width: 100%; +} + +/* + Directories + */ +div.directory { + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + width: auto; +} + +table.directory { + font-family: var(--font-family); + font-size: var(--page-font-size); + font-weight: normal; +} + +.directory td.entry { + padding: var(--spacing-small); + display: flex; + align-items: center; +} + +.directory tr.even { + background-color: var(--odd-color); +} + +.icona { + width: auto; + height: auto; + margin: 0 var(--spacing-small); +} + +.icon { + background: var(--primary-color); + width: 18px; + height: 18px; + line-height: 18px; +} + +.iconfopen, +.icondoc, +.iconfclosed { + background-position: center; + margin-bottom: 0; +} + +.icondoc { + filter: saturate(0.2); +} + +@media screen and (max-width: 767px) { + div.directory { + margin-left: calc(0px - var(--spacing-medium)); + margin-right: calc(0px - var(--spacing-medium)); + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) .iconfopen, + html:not(.light-mode) .iconfclosed { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode .iconfopen, +html.dark-mode .iconfclosed { + filter: hue-rotate(180deg) invert(); +} + +/* + Class list + */ + +.classindex dl.odd { + background: var(--odd-color); + border-radius: var(--border-radius-small); +} + +@media screen and (max-width: 767px) { + .classindex { + margin: 0 calc(0px - var(--spacing-small)); + } +} + +/* + Footer and nav-path + */ + +#nav-path { + margin-bottom: -1px; + width: 100%; +} + +#nav-path ul { + background-image: none; + background: var(--page-background-color); + border: none; + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + font-size: var(--navigation-font-size); +} + +img.footer { + width: 60px; +} + +.navpath li.footer { + color: var(--page-secondary-foreground-color); +} + +address.footer { + margin-bottom: var(--spacing-large); +} + +#nav-path li.navelem { + background-image: none; + display: flex; + align-items: center; +} + +.navpath li.navelem a { + text-shadow: none; + display: inline-block; + color: var(--primary-color) !important; +} + +.navpath li.navelem b { + color: var(--primary-dark-color); + font-weight: 500; +} + +li.navelem { + padding: 0; + margin-left: -8px; +} + +li.navelem:first-child { + margin-left: var(--spacing-large); +} + +li.navelem:first-child:before { + display: none; +} + +#nav-path li.navelem:after { + content: ""; + border: 5px solid var(--page-background-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(4.2); + z-index: 10; + margin-left: 6px; +} + +#nav-path li.navelem:before { + content: ""; + border: 5px solid var(--separator-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(3.2); + margin-right: var(--spacing-small); +} + +.navpath li.navelem a:hover { + color: var(--primary-color); +} + +/* + Optional Dark mode toggle button +*/ + +doxygen-awesome-dark-mode-toggle { + margin: 0 0 0 var(--spacing-small); + padding: 0; + width: var(--searchbar-height); + height: var(--searchbar-height); + background: none; + border: none; + font-size: 23px; + border-radius: var(--border-radius-medium); + vertical-align: middle; + text-align: center; + line-height: var(--searchbar-height); +} + +doxygen-awesome-dark-mode-toggle:hover { + background: var(--separator-color); +} + +doxygen-awesome-dark-mode-toggle:after { + content: var(--darkmode-toggle-button-icon); +} + +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + */ + +html { + /* side nav width. MUST be = `TREEVIEW_WIDTH`. + * Make sure it is wide enough to contain the page title (logo + title + version) + */ + --side-nav-fixed-width: 340px; + --menu-display: none; + + --top-height: 120px; +} + +@media screen and (min-width: 768px) { + html { + --searchbar-background: var(--page-background-color); + } + + #side-nav { + min-width: var(--side-nav-fixed-width); + max-width: var(--side-nav-fixed-width); + top: var(--top-height); + } + + #nav-tree, + #side-nav { + height: calc(100vh - var(--top-height)) !important; + } + + #nav-tree { + padding: 0; + } + + #top { + display: block; + border-bottom: none; + height: var(--top-height); + margin-bottom: calc(0px - var(--top-height)); + max-width: var(--side-nav-fixed-width); + background: var(--side-nav-background); + } + #main-nav { + float: left; + padding-right: 0; + } + + .ui-resizable-handle { + cursor: default; + width: 1px !important; + box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color); + } + + #nav-path { + position: fixed; + right: 0; + left: var(--side-nav-fixed-width); + bottom: 0; + width: auto; + } + + #doc-content { + height: calc(100vh - 31px) !important; + padding-bottom: calc(3 * var(--spacing-large)); + padding-top: calc(var(--top-height) - 80px); + box-sizing: border-box; + margin-left: var(--side-nav-fixed-width) !important; + } + + #MSearchBox { + width: calc( + var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) + ); + } + + #MSearchField { + width: calc( + var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px + ); + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: auto; + } +} diff --git a/photon-client/package.json b/photon-client/package.json index c201232839..a69b556024 100644 --- a/photon-client/package.json +++ b/photon-client/package.json @@ -7,6 +7,7 @@ "build": "run-p build-only", "preview": "vite preview --port 4173", "build-only": "vite build", + "build-demo": "vite build --mode demo", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", "format": "prettier --write src/", "lint-ci": "eslint . --max-warnings 0 --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", diff --git a/photon-client/src/App.vue b/photon-client/src/App.vue index 80711960f1..518ad39833 100644 --- a/photon-client/src/App.vue +++ b/photon-client/src/App.vue @@ -8,43 +8,45 @@ import PhotonSidebar from "@/components/app/photon-sidebar.vue"; import PhotonLogView from "@/components/app/photon-log-view.vue"; import PhotonErrorSnackbar from "@/components/app/photon-error-snackbar.vue"; -const websocket = new AutoReconnectingWebsocket( - `ws://${inject("backendHost")}/websocket_data`, - () => { - useStateStore().$patch({ backendConnected: true }); - }, - (data) => { - if (data.log !== undefined) { - useStateStore().addLogFromWebsocket(data.log); +const is_demo = import.meta.env.MODE === "demo"; +if (!is_demo) { + const websocket = new AutoReconnectingWebsocket( + `ws://${inject("backendHost")}/websocket_data`, + () => { + useStateStore().$patch({ backendConnected: true }); + }, + (data) => { + if (data.log !== undefined) { + useStateStore().addLogFromWebsocket(data.log); + } + if (data.settings !== undefined) { + useSettingsStore().updateGeneralSettingsFromWebsocket(data.settings); + } + if (data.cameraSettings !== undefined) { + useCameraSettingsStore().updateCameraSettingsFromWebsocket(data.cameraSettings); + } + if (data.ntConnectionInfo !== undefined) { + useStateStore().updateNTConnectionStatusFromWebsocket(data.ntConnectionInfo); + } + if (data.metrics !== undefined) { + useSettingsStore().updateMetricsFromWebsocket(data.metrics); + } + if (data.updatePipelineResult !== undefined) { + useStateStore().updateBackendResultsFromWebsocket(data.updatePipelineResult); + } + if (data.mutatePipelineSettings !== undefined && data.cameraIndex !== undefined) { + useCameraSettingsStore().changePipelineSettingsInStore(data.mutatePipelineSettings, data.cameraIndex); + } + if (data.calibrationData !== undefined) { + useStateStore().updateCalibrationStateValuesFromWebsocket(data.calibrationData); + } + }, + () => { + useStateStore().$patch({ backendConnected: false }); } - if (data.settings !== undefined) { - useSettingsStore().updateGeneralSettingsFromWebsocket(data.settings); - } - if (data.cameraSettings !== undefined) { - useCameraSettingsStore().updateCameraSettingsFromWebsocket(data.cameraSettings); - } - if (data.ntConnectionInfo !== undefined) { - useStateStore().updateNTConnectionStatusFromWebsocket(data.ntConnectionInfo); - } - if (data.metrics !== undefined) { - useSettingsStore().updateMetricsFromWebsocket(data.metrics); - } - if (data.updatePipelineResult !== undefined) { - useStateStore().updateBackendResultsFromWebsocket(data.updatePipelineResult); - } - if (data.mutatePipelineSettings !== undefined && data.cameraIndex !== undefined) { - useCameraSettingsStore().changePipelineSettingsInStore(data.mutatePipelineSettings, data.cameraIndex); - } - if (data.calibrationData !== undefined) { - useStateStore().updateCalibrationStateValuesFromWebsocket(data.calibrationData); - } - }, - () => { - useStateStore().$patch({ backendConnected: false }); - } -); - -useStateStore().$patch({ websocket: websocket }); + ); + useStateStore().$patch({ websocket: websocket }); +}