[
  {
    "path": ".clang-format",
    "content": "---\nLanguage:        Cpp\n# BasedOnStyle:  LLVM\nAccessModifierOffset: -2\nAlignAfterOpenBracket: Align\nAlignConsecutiveAssignments: false\nAlignConsecutiveDeclarations: false\nAlignEscapedNewlines: Right\nAlignOperands:   true\nAlignTrailingComments: true\nAllowAllParametersOfDeclarationOnNextLine: true\nAllowShortBlocksOnASingleLine: false\nAllowShortCaseLabelsOnASingleLine: false\nAllowShortFunctionsOnASingleLine: All\nAllowShortIfStatementsOnASingleLine: false\nAllowShortLoopsOnASingleLine: false\nAlwaysBreakAfterDefinitionReturnType: None\nAlwaysBreakAfterReturnType: None\nAlwaysBreakBeforeMultilineStrings: false\nAlwaysBreakTemplateDeclarations: false\nBinPackArguments: true\nBinPackParameters: true\nBraceWrapping:   \n  AfterClass:      false\n  AfterControlStatement: false\n  AfterEnum:       false\n  AfterFunction:   false\n  AfterNamespace:  false\n  AfterObjCDeclaration: false\n  AfterStruct:     false\n  AfterUnion:      false\n  AfterExternBlock: false\n  BeforeCatch:     false\n  BeforeElse:      false\n  IndentBraces:    false\n  SplitEmptyFunction: true\n  SplitEmptyRecord: true\n  SplitEmptyNamespace: true\nBreakBeforeBinaryOperators: None\nBreakBeforeBraces: Attach\nBreakBeforeInheritanceComma: false\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializersBeforeComma: false\nBreakConstructorInitializers: BeforeColon\nBreakAfterJavaFieldAnnotations: false\nBreakStringLiterals: true\nColumnLimit:     80\nCommentPragmas:  '^ IWYU pragma:'\nCompactNamespaces: false\nConstructorInitializerAllOnOneLineOrOnePerLine: true\nConstructorInitializerIndentWidth: 4\nContinuationIndentWidth: 4\nCpp11BracedListStyle: true\nDerivePointerAlignment: false\nDisableFormat:   false\nExperimentalAutoDetectBinPacking: false\nFixNamespaceComments: true\nForEachMacros:   \n  - foreach\n  - Q_FOREACH\n  - BOOST_FOREACH\nIncludeBlocks:   Preserve\nIncludeCategories: \n  - Regex:           '^\"(llvm|llvm-c|clang|clang-c)/'\n    Priority:        2\n  - Regex:           '^(<|\"(gtest|gmock|isl|json)/)'\n    Priority:        3\n  - Regex:           '.*'\n    Priority:        1\nIncludeIsMainRegex: '(Test)?$'\nIndentCaseLabels: false\nIndentPPDirectives: None\nIndentWidth:     2\nIndentWrappedFunctionNames: false\nJavaScriptQuotes: Leave\nJavaScriptWrapImports: true\nKeepEmptyLinesAtTheStartOfBlocks: true\nMacroBlockBegin: ''\nMacroBlockEnd:   ''\nMaxEmptyLinesToKeep: 1\nNamespaceIndentation: None\nObjCBlockIndentWidth: 2\nObjCSpaceAfterProperty: false\nObjCSpaceBeforeProtocolList: true\nPenaltyBreakAssignment: 2\nPenaltyBreakBeforeFirstCallParameter: 19\nPenaltyBreakComment: 300\nPenaltyBreakFirstLessLess: 120\nPenaltyBreakString: 1000\nPenaltyExcessCharacter: 1000000\nPenaltyReturnTypeOnItsOwnLine: 60\nPointerAlignment: Right\nReflowComments:  false\nSortIncludes:    true\nSortUsingDeclarations: true\nSpaceAfterCStyleCast: false\nSpaceAfterTemplateKeyword: true\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeParens: ControlStatements\nSpaceInEmptyParentheses: false\nSpacesBeforeTrailingComments: 1\nSpacesInAngles:  false\nSpacesInContainerLiterals: true\nSpacesInCStyleCastParentheses: false\nSpacesInParentheses: false\nSpacesInSquareBrackets: false\nStandard:        Cpp11\nTabWidth:        8\nUseTab:          Never\n...\n\n"
  },
  {
    "path": ".clang-tidy",
    "content": "---\n# We should aim to fix the code and re-enable most of the rules here.\n# The following were disabled due to false positives:\n# - clang-analyzer-cplusplus.NewDeleteLeaks: Finds a leak inside std::function (clang-tidy 15.0.7)\nChecks: >\n    bugprone-*,\n    cert-*,\n    clang-analyzer-*,\n    clang-diagnostic-*,\n    cppcoreguidelines-*,\n    hicpp-*,\n    misc-*,\n    modernize-*,\n    performance-*,\n    portability-*,\n    readability-*,\n    -bugprone-easily-swappable-parameters,\n    -bugprone-branch-clone,\n    -cert-env33-c,\n    -clang-analyzer-core.CallAndMessage,\n    -clang-analyzer-optin.cplusplus.UninitializedObject,\n    -clang-analyzer-security.insecureAPI.strcpy,\n    -clang-analyzer-cplusplus.NewDeleteLeaks,\n    -clang-diagnostic-unused-parameter,\n    -cppcoreguidelines-avoid-c-arrays,\n    -cppcoreguidelines-avoid-magic-numbers,\n    -cppcoreguidelines-init-variables,\n    -cppcoreguidelines-macro-usage,\n    -cppcoreguidelines-owning-memory,\n    -cppcoreguidelines-explicit-virtual-functions,\n    -cppcoreguidelines-pro-bounds-array-to-pointer-decay,\n    -cppcoreguidelines-pro-bounds-pointer-arithmetic,\n    -cppcoreguidelines-pro-type-cstyle-cast,\n    -cppcoreguidelines-pro-type-vararg,\n    -cppcoreguidelines-special-member-functions,\n    -hicpp-avoid-c-arrays,\n    -hicpp-explicit-conversions,\n    -hicpp-no-array-decay,\n    -hicpp-signed-bitwise,\n    -hicpp-special-member-functions,\n    -hicpp-use-override,\n    -hicpp-vararg,\n    -misc-definitions-in-headers,\n    -misc-include-cleaner,\n    -misc-non-private-member-variables-in-classes,\n    -modernize-avoid-c-arrays,\n    -modernize-make-unique,\n    -modernize-pass-by-value,\n    -modernize-use-nodiscard,\n    -modernize-use-override,\n    -modernize-use-trailing-return-type,\n    -modernize-use-using,\n    -performance-enum-size,\n    -performance-unnecessary-value-param,\n    -readability-convert-member-functions-to-static,\n    -readability-else-after-return,\n    -readability-qualified-auto,\n    -readability-function-cognitive-complexity,\n    -readability-implicit-bool-conversion,\n    -readability-inconsistent-declaration-parameter-name,\n    -readability-magic-numbers\nCheckOptions:\n  # We use short variables like \"w\"\n  - key:   readability-identifier-length.MinimumVariableNameLength\n    value: 1\n  # We use short parameters like \"w\"\n  - key:   readability-identifier-length.MinimumParameterNameLength\n    value: 1\n  # We have many value variables that aren't declared as const.\n  - key:   misc-const-correctness.AnalyzeValues\n    value: 0\nHeaderFilterRegex: webview\\.h$\n"
  },
  {
    "path": ".gitattributes",
    "content": "*.h linguist-language=c\n"
  },
  {
    "path": ".github/actions/cmake/action.yaml",
    "content": "name: CMake build\ndescription: Build project using CMake\ninputs:\n  artifacts-name:\n    description: Artifacts name\n    required: false\n  build-dir:\n    description: CMake build directory\n    required: false\n    default: build\n  build-config-debug:\n    description: CMake build config for debug\n    required: false\n    default: Debug\n  build-config-release:\n    description: CMake build config for release\n    required: false\n    default: Release\n  build-config-profile:\n    description: CMake build config for profiling\n    required: false\n    default: Profile\n  coverage:\n    description: Enable code coverage?\n    required: false\n  cmake-options:\n    description: Sets extra CMake options in the form [\"K=V\", ...]\n    required: false\n  gcov:\n    description: gcov executable\n    required: false\n    default: gcov\n  gcovr-config:\n    description: gcovr config file\n    required: false\n    default: gcovr.ci.cfg\n  gcovr-version:\n    description: gcovr version\n    required: false\n    default: '7.2'\n  generator:\n    description: CMake generator\n    required: false\n    default: Ninja\n  package:\n    description: Package?\n    required: false\n  package-source:\n    description: Package source code?\n    required: false\n  shell:\n    description: Shell\n    required: false\n    default: bash\n  source-dir:\n    description: CMake source directory\n    required: false\n    default: .\n  test-timeout:\n    description: Test timeout in seconds\n    required: false\n    default: '60'\n  test-wrapper-cmd:\n    description: Test wrapper command\n    required: false\n  upload-coverage-artifacts:\n    description: Upload coverage artifacts?\n    required: false\n  upload-package-artifacts:\n    description: Upload package artifacts?\n    required: false\nruns:\n  using: composite\n  steps:\n    - if: inputs.coverage != '' && fromJson(inputs.coverage)\n      name: gcov version\n      run: ${{ inputs.gcov }} --version\n      shell: ${{ inputs.shell }}\n\n    - if: inputs.coverage != '' && fromJson(inputs.coverage)\n      name: Install gcovr\n      run: pip install \"gcovr==${{ inputs.gcovr-version }}\"\n      shell: ${{ inputs.shell }}\n\n    - name: Generate build config names\n      id: generate-build-config-names\n      run: |\n        configs=()\n        if [[ \"${{ inputs.coverage }}\" == \"true\" ]]; then\n          configs+=(\"${{ inputs.build-config-profile }}\")\n        else\n          configs+=(\"${{ inputs.build-config-debug }}\")\n          configs+=(\"${{ inputs.build-config-release }}\")\n        fi\n        echo \"configs=${configs[@]}\" >> \"${GITHUB_OUTPUT}\"\n      shell: bash\n\n    - name: Parse CMake options\n      uses: actions/github-script@v7\n      id: cmake-options\n      env:\n        OPTIONS: ${{ inputs.cmake-options }}\n      with:\n        script: return JSON.parse(process.env.OPTIONS).join(\"\\n\")\n        result-encoding: string\n\n    - name: Configure\n      env:\n        OPTIONS: ${{ steps.cmake-options.outputs.result }}\n      run: |\n        cmake_cmd=(\n          cmake\n          -G \"${{ inputs.generator }}\"\n          -B \"${{ inputs.build-dir }}\"\n          -S \"${{ inputs.source-dir }}\"\n        )\n        while read opt; do\n          if [[ ! -z \"${opt}\" ]]; then\n            cmake_cmd+=(-D \"${opt}\")\n          fi\n        done << EOF\n        ${OPTIONS}\n        EOF\n        \"${cmake_cmd[@]}\"\n      shell: ${{ inputs.shell }}\n\n    - name: Build\n      run: |\n        configs=(${{ steps.generate-build-config-names.outputs.configs }})\n        for config in \"${configs[@]}\"; do\n          cmake_cmd=(\n            cmake\n            --build \"${{ inputs.build-dir }}\"\n            --config \"${config}\"\n          )\n          \"${cmake_cmd[@]}\"\n        done\n      shell: ${{ inputs.shell }}\n\n    - name: Test\n      run: |\n        configs=(${{ steps.generate-build-config-names.outputs.configs }})\n        for config in \"${configs[@]}\"; do\n          cmake_cmd=()\n          if [[ ! -z \"${{ inputs.test-wrapper-cmd }}\" ]]; then\n            cmake_cmd+=(\"${{ inputs.test-wrapper-cmd }}\")\n          fi\n          cmake_cmd+=(\n            ctest\n            --test-dir \"${{ inputs.build-dir }}\"\n            --output-on-failure\n            --build-config \"${config}\"\n          )\n          if [[ ! -z \"${{ inputs.test-timeout }}\" ]]; then\n            cmake_cmd+=(--timeout \"${{ inputs.test-timeout }}\")\n          fi\n          \"${cmake_cmd[@]}\"\n        done\n      shell: ${{ inputs.shell }}\n\n    - if: inputs.package != '' && fromJson(inputs.package)\n      name: Create packages\n      run: cpack -G External -C \"${{ inputs.build-config-debug }};${{ inputs.build-config-release }}\" --config CPackConfig.cmake\n      working-directory: ${{ inputs.build-dir }}\n      shell: ${{ inputs.shell }}\n\n    - if: inputs.package-source != '' && fromJson(inputs.package-source)\n      name: Create source package\n      run: cpack --config CPackSourceConfig.cmake\n      working-directory: ${{ inputs.build-dir }}\n      shell: ${{ inputs.shell }}\n\n    - if: inputs.coverage != '' && fromJson(inputs.coverage)\n      name: Generate coverage data\n      id: prepare-coverage-artifacts\n      run: |\n        artifact_dir=\"temp_${RANDOM}/${{ inputs.artifacts-name }}\"\n\n        gcovr_args=(\n          --config \"${{ inputs.gcovr-config }}\"\n          --json \"${artifact_dir}/coverage.json\"\n        )\n        if [[ ! -z \"${{ inputs.gcov }}\" ]]; then\n          gcovr_args+=(--gcov-executable \"${{ inputs.gcov }}\")\n        fi\n\n        mkdir -p \"${artifact_dir}\"\n        gcovr \"${gcovr_args[@]}\"\n\n        echo \"upload-dir=${artifact_dir}\" >> \"${GITHUB_OUTPUT}\"\n      shell: ${{ inputs.shell }}\n\n    - if: (inputs.upload-package-artifacts != '' && fromJson(inputs.upload-package-artifacts)) && ((inputs.package != '' && fromJson(inputs.package)) || (inputs.package-source != '' && fromJson(inputs.package-source)))\n      name: Upload package artifacts\n      uses: actions/upload-artifact@v4\n      with:\n        name: package_${{ inputs.artifacts-name }}\n        path: |\n          ${{ inputs.build-dir }}/*.gz\n          ${{ inputs.build-dir }}/*.zip\n        retention-days: 1\n        if-no-files-found: error\n\n    - if: (inputs.upload-coverage-artifacts != '' && fromJson(inputs.upload-coverage-artifacts)) && (inputs.coverage != '' && fromJson(inputs.coverage))\n      name: Upload coverage artifacts\n      uses: actions/upload-artifact@v4\n      with:\n        name: test_coverage_data_${{ inputs.artifacts-name }}\n        path: ${{ steps.prepare-coverage-artifacts.outputs.upload-dir }}\n        retention-days: 1\n        if-no-files-found: error\n\n    - if: inputs.coverage != '' && fromJson(inputs.coverage)\n      name: Clean up temporary coverage files\n      run: rm -rf \"${{ steps.prepare-coverage-artifacts.outputs.upload-dir }}\"\n      shell: ${{ inputs.shell }}\n"
  },
  {
    "path": ".github/actions/setup-env/action.yaml",
    "content": "name: Set up environment\ndescription: Sets up the environment by checking out code, installing required packages, etc.\ninputs:\n  apt:\n    description: APT package names\n    required: false\n  msys:\n    description: MSYS2 environment\n    required: false\n  msys-pacboy:\n    description: MSYS2 packages (pacboy)\n    required: false\n  webkitgtk-api:\n    description: WebKitGTK API version\n    required: false\nruns:\n  using: composite\n  steps:\n    - if: runner.os == 'Linux'\n      name: Get APT packages for WebKitGTK\n      id: apt-webkitgtk\n      run: |\n        packages=()\n        if [[ \"${{ inputs.webkitgtk-api }}\" == \"6.0\" ]]; then\n          packages+=(libgtk-4-dev libwebkitgtk-6.0-dev)\n        elif [[ \"${{ inputs.webkitgtk-api }}\" == \"4.1\" ]]; then\n          packages+=(libgtk-3-dev libwebkit2gtk-4.1-dev)\n        elif [[ \"${{ inputs.webkitgtk-api }}\" == \"4.0\" ]]; then\n          packages+=(libgtk-3-dev libwebkit2gtk-4.0-dev)\n        fi\n        echo \"packages=${packages[@]}\" >> \"${GITHUB_OUTPUT}\"\n      shell: bash\n\n    - if: runner.os == 'Linux'\n      name: Install packages (APT)\n      run: |\n        packages=(${{ inputs.apt }} ${{ steps.apt-webkitgtk.outputs.packages }})\n        sudo apt-get update\n        sudo apt-get install --no-install-recommends -y \\\n          cmake \\\n          doxygen \\\n          graphviz \\\n          ninja-build \\\n          python3 \\\n          python3-lxml \\\n          python3-markupsafe \\\n          python3-pip \\\n          xvfb \\\n          \"${packages[@]}\"\n      shell: bash\n\n    - if: runner.os == 'Windows' && inputs.msys != ''\n      name: Set up MSYS2\n      uses: msys2/setup-msys2@v2\n      with:\n        msystem: ${{ inputs.msys }}\n        update: false\n        install: base-devel\n        pacboy: >-\n          cmake:p\n          ninja:p\n          python:p\n          python-lxml:p\n          python-markupsafe:p\n          python-pip:p\n          toolchain:p\n          ${{ inputs.msys-pacboy }}\n"
  },
  {
    "path": ".github/issue_template.md",
    "content": "<!--\n\nThanks for filing an issue! If this is a question or feature request, just delete\neverything here and write out the request, providing as much context as you can.\n\n-->\n\n### What OS are you using (`uname -a`, or Windows version)?\n\n<!-- \nPlease specify your operating system version and architecture (i686/amd64 etc).\nIf you're running Windows - please also provide your IE version.\n-->\n\n### What programming language are you using (C/C++/Go/Rust)?\n\n<!--\n`gcc --version`\n`clang --version`\n`go version`\n`rustc --version`\n-->\n\n### What did you expect to see and what you saw instead?\n\n<!--\nYour issue may already be reported! Please search on the issue tracker before creating a new one.\nIf your issue has not been reported yet - please describe your problem with as much details as you can.\nThanks you.\n-->\n"
  },
  {
    "path": ".github/workflows/build.yaml",
    "content": "name: Build\non:\n  workflow_call:\n    inputs:\n      coverage:\n        type: boolean\n        description: Enable code coverage?\n        required: false\n        default: true\n      gcovr-version:\n        type: string\n        description: gcovr version\n        required: false\n      pr:\n        type: boolean\n        description: Is this a pull request build?\n        required: false\n        default: false\njobs:\n  load-matrix:\n    runs-on: ubuntu-22.04\n    outputs:\n      matrix: ${{ steps.load-matrix.outputs.result }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Load matrix file\n        id: load-matrix\n        uses: actions/github-script@v7\n        env:\n          PR: ${{ inputs.pr }}\n          ENABLE_COVERAGE: ${{ inputs.coverage }}\n        with:\n          script: |\n            const csv = require(\"./.github/workflows/csv.js\");\n            const path = require(\"node:path\");\n            const schema = require(\"./.github/workflows/build_matrix_schema.json\");\n            let include = csv.loadFile(path.join(\".github\", \"workflows\", \"build_matrix.csv\"), schema);\n\n            // Generate IDs that match line numbers in the CSV file, making it more\n            // convenient to work with the file and review changes made to it.\n            [...include.keys()].forEach(n => include[n].id = 2 + n);\n\n            // Filters\n            include = include.filter(x => JSON.parse(process.env.PR) === x[\"pr-only\"]);\n            include = include.filter(x => x[\"job-type\"] !== \"coverage\" || JSON.parse(process.env.ENABLE_COVERAGE));\n\n            const matrix = { include };\n            console.log(matrix);\n            return matrix;\n\n  build:\n    needs: load-matrix\n    name: ${{ matrix.job-type }} (${{ matrix.id }}, ${{ matrix.os }}, c++${{ matrix.cxx-std }}, ${{ matrix.arch }}, ${{ matrix.toolchain }}${{ matrix.toolchain-executable-suffix }}${{ matrix.job-name-suffix }})\n    runs-on: ${{ matrix.image }}\n    strategy:\n      fail-fast: false\n      matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Set up environment\n        uses: ./.github/actions/setup-env\n        with:\n          apt: ${{ matrix.apt }}\n          msys: ${{ matrix.msys }}\n          msys-pacboy: ${{ matrix.msys-pacboy }}\n          webkitgtk-api: ${{ matrix.webkitgtk-api }}\n\n      - name: Build CMake options\n        uses: actions/github-script@v7\n        id: cmake-options\n        env:\n          MATRIX: ${{ toJson(matrix) }}\n        with:\n          script: |\n            const matrix = JSON.parse(process.env.MATRIX);\n            const option = (k, v) => v === undefined ? undefined : [k, ({\n                boolean: () => v ? \"ON\" : \"OFF\"\n              }[typeof v] || (() => v))()\n            ].join(\"=\");\n            return [\n              option(\"CMAKE_CXX_STANDARD\", matrix[\"cxx-std\"]),\n              option(\"CMAKE_OSX_DEPLOYMENT_TARGET\", matrix[\"osx-deployment-target\"]),\n              option(\"CMAKE_TOOLCHAIN_FILE\", `cmake/toolchains/${matrix[\"arch\"]}-${matrix[\"toolchain\"]}.cmake`),\n              option(\"WEBVIEW_BUILD_AMALGAMATION\", matrix[\"package-amalgamation\"]),\n              option(\"WEBVIEW_BUILD_DOCS\", matrix[\"package-docs\"]),\n              option(\"WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX\", matrix[\"toolchain-executable-suffix\"]),\n              option(\"WEBVIEW_USE_STATIC_MSVC_RUNTIME\", matrix[\"msvc-mt\"]),\n              // We check formatting separately\n              option(\"WEBVIEW_ENABLE_CLANG_FORMAT\", false),\n              option(\"WEBVIEW_ENABLE_CLANG_TIDY\", matrix[\"checks\"]),\n              // Please enable strict clang-tidy when issues have been fixed\n              option(\"WEBVIEW_STRICT_CLANG_TIDY\", matrix[\"strict-clang-tidy\"]),\n              option(\"WEBVIEW_WEBKITGTK_API\", matrix[\"webkitgtk-api\"]),\n              // Packaging\n              option(\"WEBVIEW_ENABLE_PACKAGING\", matrix[\"package\"]),\n              option(\"WEBVIEW_PACKAGE_AMALGAMATION\", matrix[\"package-amalgamation\"]),\n              option(\"WEBVIEW_PACKAGE_DOCS\", matrix[\"package-docs\"]),\n              option(\"WEBVIEW_PACKAGE_HEADERS\", matrix[\"package-headers\"]),\n              option(\"WEBVIEW_PACKAGE_LIB\", matrix[\"package-lib\"]),\n            ].filter(v => v !== undefined).filter(v => {\n              console.log(v);\n              return true;\n            });\n\n      - name: CMake\n        uses: ./.github/actions/cmake\n        with:\n          artifacts-name: ${{ matrix.id }}\n          build-dir: build\n          cmake-options: ${{ steps.cmake-options.outputs.result }}\n          generator: ${{ matrix.generator }}\n          package: ${{ matrix.package }}\n          package-source: ${{ matrix.package-source }}\n          shell: ${{ matrix.shell }}\n          source-dir: .\n          test-wrapper-cmd: ${{ matrix.test-wrapper-cmd }}\n          upload-package-artifacts: ${{ matrix.package && !inputs.pr }}\n          # Specific to code coverage\n          coverage: ${{ inputs.coverage && matrix.job-type == 'coverage' }}\n          gcov: ${{ matrix.gcov }}\n          gcovr-version: ${{ inputs.gcovr-version }}\n          upload-coverage-artifacts: ${{ inputs.coverage && matrix.job-type == 'coverage' && !inputs.pr }}\n"
  },
  {
    "path": ".github/workflows/build_matrix.csv",
    "content": "job-type,os,image,arch,cxx-std,toolchain,toolchain-executable-suffix,generator,pr-only,checks,strict-clang-tidy,package,package-amalgamation,package-docs,package-headers,package-lib,package-source,shell,msvc-mt,msys,msys-pacboy,apt,gcov,osx-deployment-target,test-wrapper-cmd,webkitgtk-api,job-name-suffix,comments\npackage,linux,ubuntu-22.04,host,11,gnu,-12,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,14,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,17,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,20,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,23,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,11,gnu,-12,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,14,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,17,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,20,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,23,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,11,gnu,-12,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,14,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,17,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,20,gnu,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-12 g++-12,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,11,llvm,-15,Ninja Multi-Config,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,14,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,17,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,20,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,6.0,\", webkitgtk6.0\",\npackage,linux,ubuntu-22.04,host,23,llvm,-15,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,6.0,\", webkitgtk6.0\",Checks disabled because clang-tidy-15 segfaults\npackage,linux,ubuntu-22.04,host,11,llvm,-15,Ninja Multi-Config,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,14,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,17,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,20,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.1,\", webkitgtk4.1\",\npackage,linux,ubuntu-22.04,host,23,llvm,-15,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.1,\", webkitgtk4.1\",Checks disabled because clang-tidy-15 segfaults\npackage,linux,ubuntu-22.04,host,11,llvm,-15,Ninja Multi-Config,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,14,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,17,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,20,llvm,-15,Ninja Multi-Config,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,,,xvfb-run,4.0,\", webkitgtk4.0\",\npackage,linux,ubuntu-22.04,host,11,gnu,-10,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,gcc-10 g++-10,,,xvfb-run,4.0,\", webkitgtk4.0\",Previously used the ubuntu-20.04 image where GCC 10 was latest\npackage,linux,ubuntu-22.04,host,11,llvm,-12,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-12 clang++-12 clang-tidy-12,,,xvfb-run,4.0,\", webkitgtk4.0\",Previously used the ubuntu-20.04 image where Clang 12 was latest\npackage,macos,macos-14,universal,11,macos-llvm,,Xcode,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,,,,,,10.9,,,,\npackage,macos,macos-14,universal,14,macos-llvm,,Xcode,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,,,10.9,,,,\npackage,macos,macos-14,universal,17,macos-llvm,,Xcode,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,,,10.9,,,,\npackage,macos,macos-14,universal,20,macos-llvm,,Xcode,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,,,10.9,,,,\npackage,macos,macos-14,universal,23,macos-llvm,,Xcode,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,,,10.9,,,,\npackage,windows,ubuntu-22.04,x86_64,11,w64-mingw32,-posix,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,mingw-w64,,,,,,\npackage,windows,ubuntu-22.04,x86_64,14,w64-mingw32,-posix,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,mingw-w64,,,,,,\npackage,windows,ubuntu-22.04,x86_64,17,w64-mingw32,-posix,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,mingw-w64,,,,,,\npackage,windows,ubuntu-22.04,x86_64,20,w64-mingw32,-posix,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,mingw-w64,,,,,,\npackage,windows,ubuntu-22.04,i686,11,w64-mingw32,-posix,Ninja Multi-Config,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,mingw-w64,,,,,,\npackage,windows,windows-2022,arm64,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,TRUE,,,,,,,,\", mt\",\npackage,windows,windows-2022,x86_64,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,TRUE,,,,,,,,\", mt\",\npackage,windows,windows-2022,i686,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,TRUE,,,,,,,,\", mt\",\npackage,windows,windows-2022,arm64,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,x86_64,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,x86_64,17,windows-msvc,,Visual Studio 17 2022,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,x86_64,20,windows-msvc,,Visual Studio 17 2022,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,x86_64,23,windows-msvc,,Visual Studio 17 2022,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,i686,14,windows-msvc,,Visual Studio 17 2022,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,bash,FALSE,,,,,,,,\", md\",\npackage,windows,windows-2022,x86_64,11,msys2-gnu-ucrt64,,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,UCRT64,,,,,,,\", UCRT64\",\npackage,windows,windows-2022,x86_64,11,msys2-llvm-clang64,,Ninja Multi-Config,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,clang-tools-extra:p,,,,,,\", CLANG64\",Please enable strict clang-tidy when issues have been fixed.\npackage,windows,windows-2022,x86_64,14,msys2-llvm-clang64,,Ninja Multi-Config,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,clang-tools-extra:p,,,,,,\", CLANG64\",Please enable strict clang-tidy when issues have been fixed.\npackage,windows,windows-2022,x86_64,17,msys2-llvm-clang64,,Ninja Multi-Config,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,clang-tools-extra:p,,,,,,\", CLANG64\",Please enable strict clang-tidy when issues have been fixed.\npackage,windows,windows-2022,x86_64,20,msys2-llvm-clang64,,Ninja Multi-Config,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,clang-tools-extra:p,,,,,,\", CLANG64\",Please enable strict clang-tidy when issues have been fixed.\npackage,windows,windows-2022,x86_64,23,msys2-llvm-clang64,,Ninja Multi-Config,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,clang-tools-extra:p,,,,,,\", CLANG64\",Please enable strict clang-tidy when issues have been fixed.\ncoverage,linux,ubuntu-22.04,host,11,llvm,,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,llvm-cov-15 gcov,,xvfb-run,6.0,\", webkitgtk6.0\",\ncoverage,linux,ubuntu-22.04,host,11,llvm,,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,llvm-cov-15 gcov,,xvfb-run,4.1,\", webkitgtk4.1\",\ncoverage,linux,ubuntu-22.04,host,11,llvm,-15,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,clang-15 clang++-15 clang-tidy-15,llvm-cov-15 gcov,,xvfb-run,4.0,\", webkitgtk4.0\",\ncoverage,macos,macos-14,universal,11,macos-llvm,-15,Xcode,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,bash,,,,,xcrun llvm-cov gcov,,,,,\ncoverage,windows,windows-2022,x86_64,11,msys2-llvm-clang64,,Ninja Multi-Config,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,msys2 {0},,CLANG64,,,llvm-cov gcov,,,,\", CLANG64\",\n"
  },
  {
    "path": ".github/workflows/build_matrix_schema.json",
    "content": "{\n    \"apt\": \"string\",\n    \"arch\": \"string\",\n    \"checks\": \"boolean\",\n    \"comments\": \"string\",\n    \"cxx-std\": \"number\",\n    \"gcov\": \"string\",\n    \"generator\": \"string\",\n    \"image\": \"string\",\n    \"job-name-suffix\": \"string\",\n    \"job-type\": \"string\",\n    \"msvc-mt\": \"boolean\",\n    \"msys\": \"string\",\n    \"msys-pacboy\": \"string\",\n    \"os\": \"string\",\n    \"osx-deployment-target\": \"string\",\n    \"package\": \"boolean\",\n    \"package-amalgamation\": \"boolean\",\n    \"package-docs\": \"boolean\",\n    \"package-headers\": \"boolean\",\n    \"package-lib\": \"boolean\",\n    \"package-source\": \"boolean\",\n    \"pr-only\": \"boolean\",\n    \"shell\": \"string\",\n    \"strict-clang-tidy\": \"boolean\",\n    \"test-wrapper-cmd\": \"string\",\n    \"toolchain\": \"string\",\n    \"toolchain-executable-suffix\": \"string\",\n    \"webkitgtk-api\": \"string\"\n}\n"
  },
  {
    "path": ".github/workflows/check.yaml",
    "content": "name: Check\non:\n  workflow_call:\njobs:\n  format:\n    runs-on: ubuntu-22.04\n    steps:\n      - uses: actions/checkout@v4\n      - run: sudo apt-get update\n      - run: sudo apt-get install --no-install-recommends -y clang-format-15\n      - run: cmake -B build -S . -D WEBVIEW_BUILD=OFF -D WEBVIEW_CLANG_FORMAT_EXE=clang-format-15\n      - run: cmake --build build --target webview_format_check\n\n  amalgamate:\n    runs-on: ${{ matrix.image }}\n    strategy:\n      fail-fast: false\n      matrix:\n        image:\n          - macos-14\n          - ubuntu-22.04\n          - windows-2022\n        python-version:\n          - \"3.9\"\n          - \"3.10\"\n          - \"3.11\"\n          - \"3.12\"\n        build-type:\n          - header\n          - shared\n          - static\n        include:\n          - image: macos-14\n            clang-format-exe: clang-format\n          - image: ubuntu-22.04\n            clang-format-exe: clang-format-15\n            test-wrapper-cmd: xvfb-run\n          - image: windows-2022\n            clang-format-exe: clang-format\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Set up environment\n        uses: ./.github/actions/setup-env\n        with:\n          apt: gcc-12 g++-12\n          msys-pacboy: clang-tools-extra:p\n          webkitgtk-api: \"6.0\"\n\n      - name: Install dependencies (Linux)\n        if: runner.os == 'Linux'\n        run: sudo apt-get update && sudo apt-get install --no-install-recommends -y clang-format-15\n\n      - name: Install dependencies (macOS)\n        if: runner.os == 'macOS'\n        run: brew install clang-format\n\n      - name: Set up Python\n        uses: actions/setup-python@v5\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: Generate amalgamated header\n        run: |\n          python3 scripts/amalgamate/amalgamate.py \\\n            --clang-format-exe \"${{ matrix.clang-format-exe }}\" \\\n            --base core \\\n            --search include \\\n            --output scripts/amalgamate/generated/webview_amalgamation.h \\\n            src\n        shell: bash\n\n      - name: Test (${{ matrix.build-type }}, Linux)\n        if: runner.os == 'Linux'\n        run: |\n          mkdir -p build\n          if [[ \"${{ matrix.build-type }}\" == \"header\" ]]; then\n            c++ main.cc --std=c++11 $(pkg-config --cflags --libs gtk4 webkitgtk-6.0) -ldl -I../generated -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"shared\" ]]; then\n            c++ webview.cc --shared --std=c++11 -fPIC $(pkg-config --cflags --libs gtk4 webkitgtk-6.0) -ldl -I../generated -DWEBVIEW_BUILD_SHARED -o build/libwebview.so\n            cc main.c build/libwebview.so --std=c99 -I../generated -DWEBVIEW_SHARED -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"static\" ]]; then\n            c++ webview.cc -c --std=c++11 $(pkg-config --cflags gtk4 webkitgtk-6.0) -ldl -I../generated -DWEBVIEW_STATIC -o build/webview.o\n            cc main.c build/webview.o --std=c99 $(pkg-config --libs gtk4 webkitgtk-6.0) -lstdc++ -I../generated -DWEBVIEW_STATIC -o build/main\n          fi\n          xvfb-run build/main\n        shell: bash\n        working-directory: scripts/amalgamate/test\n\n      - name: Test (${{ matrix.build-type }}, macOS)\n        if: runner.os == 'macOS'\n        run: |\n          mkdir -p build\n          if [[ \"${{ matrix.build-type }}\" == \"header\" ]]; then\n            c++ main.cc --std=c++11 -framework WebKit -ldl -I../generated -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"shared\" ]]; then\n            c++ webview.cc --shared --std=c++11 -fPIC -framework WebKit -ldl -I../generated -DWEBVIEW_BUILD_SHARED -o build/libwebview.so\n            cc main.c build/libwebview.so --std=c99 -I../generated -DWEBVIEW_SHARED -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"static\" ]]; then\n            c++ webview.cc -c --std=c++11 -framework WebKit -ldl -I../generated -DWEBVIEW_STATIC -o build/webview.o\n            cc main.c build/webview.o --std=c99 -framework WebKit -lstdc++ -I../generated -DWEBVIEW_STATIC -o build/main\n          fi\n          build/main\n        shell: bash\n        working-directory: scripts/amalgamate/test\n\n      - name: Test (${{ matrix.build-type }}, Windows)\n        if: runner.os == 'Windows'\n        run: |\n          mswebview2_version=1.0.1150.38\n          mswebview2_zip=$(mktemp)\n          mswebview2_dir=$(mktemp -d)\n          mswebview2_include_dir=\"${mswebview2_dir}/build/native/include\"\n          curl -sSLo \"${mswebview2_zip}\" \"https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2/${mswebview2_version}\"\n          unzip -q \"${mswebview2_zip}\" -d \"${mswebview2_dir}\"\n          libs=(-ladvapi32 -lole32 -lshell32 -lshlwapi -luser32 -lversion)\n          mkdir -p build\n          if [[ \"${{ matrix.build-type }}\" == \"header\" ]]; then\n            g++ main.cc --std=c++14  \"${libs[@]}\" \"-I${mswebview2_include_dir}\" -I../generated -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"shared\" ]]; then\n            g++ webview.cc --shared --std=c++14 -fPIC  \"${libs[@]}\" \"-I${mswebview2_include_dir}\" -I../generated -DWEBVIEW_BUILD_SHARED -o build/libwebview.so\n            gcc main.c build/libwebview.so --std=c99 -I../generated -DWEBVIEW_SHARED -o build/main\n          elif [[ \"${{ matrix.build-type }}\" == \"static\" ]]; then\n            g++ webview.cc -c --std=c++14 \"-I${mswebview2_include_dir}\" -I../generated -DWEBVIEW_STATIC -o build/webview.o\n            gcc main.c build/webview.o --std=c99 \"${libs[@]}\" -lstdc++ -I../generated -DWEBVIEW_STATIC -o build/main\n          fi\n          build/main\n        shell: bash\n        working-directory: scripts/amalgamate/test\n"
  },
  {
    "path": ".github/workflows/ci.yaml",
    "content": "name: CI\non: [push, pull_request]\ndefaults:\n  run:\n    shell: bash\njobs:\n  init:\n    runs-on: ubuntu-22.04\n    outputs:\n      gcovr-version: ${{ steps.vars.outputs.gcovr-version }}\n    steps:\n      - id: vars\n        run: |\n          echo \"gcovr-version=7.2\" >> \"${GITHUB_OUTPUT}\"\n\n  check:\n    uses: ./.github/workflows/check.yaml\n\n  build:\n    needs:\n      - check\n      - init\n    uses: ./.github/workflows/build.yaml\n    with:\n      gcovr-version: ${{ needs.init.outputs.gcovr-version }}\n\n  build-pr:\n    if: github.event_name == 'pull_request'\n    needs:\n      - check\n      - init\n    uses: ./.github/workflows/build.yaml\n    with:\n      gcovr-version: ${{ needs.init.outputs.gcovr-version }}\n      pr: true\n\n  merge-package-artifacts:\n    needs: build\n    runs-on: ubuntu-22.04\n    steps:\n      - name: Merge package artifacts\n        uses: actions/upload-artifact/merge@v4\n        with:\n          name: package\n          pattern: package_*\n          delete-merged: true\n          retention-days: 1\n\n  generate-coverage-report:\n    needs:\n      - build\n      - init\n    runs-on: ubuntu-22.04\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Python\n        run: >\n          sudo apt-get update && sudo apt-get install --no-install-recommends -y\n          python3\n          python3-lxml\n          python3-markupsafe\n          python3-pip\n\n      - name: Install gcovr\n        run: pip install \"gcovr==${{ needs.init.outputs.gcovr-version }}\"\n\n      - name: Merge test coverage artifacts\n        uses: actions/upload-artifact/merge@v4\n        with:\n          name: test_coverage_data\n          pattern: test_coverage_data_*\n          delete-merged: true\n          retention-days: 1\n          separate-directories: true\n\n      - name: Download merged test coverage artifacts\n        uses: actions/download-artifact@v4\n        with:\n          name: test_coverage_data\n\n      - name: Generate report\n        id: generate-report\n        run: |\n          tracefile_args=()\n          while read f; do\n            tracefile_args+=(--add-tracefile \"${f}\")\n          done <<< \"$(find . -type f -name \"coverage.json\")\"\n\n          artifact_dir=\"temp_${RANDOM}/report\"\n          mkdir -p \"${artifact_dir}/html\"\n\n          gcovr --config gcovr.ci.cfg --json \"${artifact_dir}/gcovr.json\" \"${tracefile_args[@]}\"\n          gcovr --config gcovr.ci.cfg --coveralls \"${artifact_dir}/coveralls.json\" --add-tracefile \"${artifact_dir}/gcovr.json\"\n          gcovr --config gcovr.ci.cfg --json-summary \"${artifact_dir}/summary.json\" --add-tracefile \"${artifact_dir}/gcovr.json\"\n          gcovr --config gcovr.ci.cfg --html-details \"${artifact_dir}/html/index.html\" --add-tracefile \"${artifact_dir}/gcovr.json\"\n\n          echo \"upload-dir=${artifact_dir}\" >> \"${GITHUB_OUTPUT}\"\n\n      - name: Upload report artifacts\n        uses: actions/upload-artifact@v4\n        with:\n          name: test_coverage_report\n          path: ${{ steps.generate-report.outputs.upload-dir }}\n          retention-days: 1\n          if-no-files-found: error\n\n      - name: Add report to CI job summary\n        uses: actions/github-script@v7\n        with:\n          script: |\n            const numberOr = (value, alternative) => Number.isNaN(value = parseInt(value)) ? alternative : value;\n            const percentValue = (value, percentSymbol = \"%\") => numberOr(value, \"-\") + percentSymbol;\n            const data = require(\"./${{ steps.generate-report.outputs.upload-dir }}/summary.json\");\n            await core.summary\n              .addHeading(\"Test Coverage Summary\")\n              .addTable([\n                [\n                  { data: \"Lines\", header: true },\n                  { data: \"Functions\", header: true },\n                  { data: \"Branches\", header: true }\n                ],\n                [\n                  `${percentValue(data.line_percent)} ${data.line_covered}/${data.line_total}`,\n                  `${percentValue(data.function_percent)} ${data.function_covered}/${data.function_total}`,\n                  `${percentValue(data.branch_percent)} ${data.branch_covered}/${data.branch_total}`\n                ]\n              ])\n              .addTable([\n                [\n                  { data: \"File\", header: true },\n                  { data: \"Lines\", header: true },\n                  { data: \"Functions\", header: true },\n                  { data: \"Branches\", header: true }\n                ],\n                ...data.files.map(file => [\n                  file.filename,\n                  `${percentValue(file.line_percent)} ${file.line_covered}/${file.line_total}`,\n                  `${percentValue(file.function_percent)} ${file.function_covered}/${file.function_total}`,\n                  `${percentValue(file.branch_percent)} ${file.branch_covered}/${file.branch_total}`\n                ])\n              ])\n              .write();\n"
  },
  {
    "path": ".github/workflows/csv.js",
    "content": "/**\n * A simple CSV parser that should be \"good enough\" for basic needs.\n */\n\nconst fs = require(\"node:fs\");\n\nfunction parseRow(line) {\n    const row = [];\n    let quoted = false;\n    let chars = [];\n    for (let i = 0; i < line.length; ++i) {\n        const c = line.charAt(i);\n        const next = line.charAt(i + 1);\n        if (quoted) {\n            if (c !== '\"') {\n                chars.push(line.charCodeAt(i));\n                continue;\n            }\n            if (next === '\"') {\n                chars.push(line.charCodeAt(i));\n                ++i;\n                continue;\n            }\n            quoted = false;\n            continue;\n        }\n        switch (c) {\n            case '\"':\n                if (next === '\"') {\n                    chars.push(line.charCodeAt(i));\n                    ++i;\n                    continue;\n                }\n                quoted = true;\n                break;\n            case \",\":\n                row.push(String.fromCodePoint(...chars));\n                chars = [];\n                break;\n            default:\n                chars.push(line.charCodeAt(i));\n                break;\n        }\n    }\n    row.push(String.fromCodePoint(...chars));\n    return row;\n}\n\nfunction parseRows(lines) {\n    return lines.map(parseRow);\n}\n\nfunction extractLines(content) {\n    return content.split(\"\\n\").filter(s => s.length > 0);\n}\n\nfunction transform(key, value, schema) {\n    const type = schema[key];\n    const converters = {\n        boolean(v) { return [\"1\", \"true\", \"TRUE\"].includes(v); },\n        string(v) { return v; },\n        number(v) { return parseInt(v); },\n    };\n    return converters[type](value);\n}\n\nfunction processRows(rows, schema) {\n    if (rows.length === 0) {\n        return [];\n    }\n    const result = [];\n    const header = rows[0];\n    if (rows.length === 1) {\n        return result;\n    }\n    for (let i = 1; i < rows.length; ++i) {\n        const rowObject = {};\n        for (const j in header) {\n            rowObject[header[j]] = transform(header[j], rows[i][j], schema);\n        }\n        result.push(rowObject);\n    }\n    return result;\n}\n\nfunction loadString(content, schema) {\n    return processRows(parseRows(extractLines(content)), schema);\n}\n\nfunction loadFile(filePath, schema) {\n    return loadString(fs.readFileSync(filePath, \"utf-8\"), schema);\n}\n\nmodule.exports = {\n    loadString,\n    loadFile\n};\n"
  },
  {
    "path": ".github/workflows/draft-release.yaml",
    "content": "name: Draft Release\non:\n  workflow_dispatch:\ndefaults:\n  run:\n    shell: bash\nconcurrency:\n  group: ${{ github.ref }}\n  cancel-in-progress: true\njobs:\n  init:\n    runs-on: ubuntu-22.04\n    outputs:\n      gcovr-version: ${{ steps.vars.outputs.gcovr-version }}\n      release-tag: ${{ steps.vars.outputs.release-tag }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - id: vars\n        run: |\n          version=\"$(cmake -P cmake/extract_version.cmake)\"\n          echo \"gcovr-version=7.2\" >> \"${GITHUB_OUTPUT}\"\n          echo \"release-tag=${version}\" >> \"${GITHUB_OUTPUT}\"\n\n  check:\n    uses: ./.github/workflows/check.yaml\n\n  build:\n    needs:\n      - check\n      - init\n    uses: ./.github/workflows/build.yaml\n    with:\n      coverage: false\n      gcovr-version: ${{ needs.init.outputs.gcovr-version }}\n\n  process-artifacts:\n    needs: build\n    runs-on: ubuntu-22.04\n    steps:\n      - name: Merge package artifacts\n        uses: actions/upload-artifact/merge@v4\n        with:\n          name: package\n          pattern: package_*\n          delete-merged: true\n          retention-days: 1\n\n      - name: Download package artifacts\n        uses: actions/download-artifact@v4\n        with:\n          name: package\n          path: dist\n\n      - name: Create checksum file\n        run: sha256sum * > SHA256SUMS\n        working-directory: dist\n        shell: bash\n\n      - name: Upload checksum artifacts\n        uses: actions/upload-artifact@v4\n        with:\n          name: package_checksum\n          path: dist/*SUMS\n          retention-days: 1\n          if-no-files-found: error\n\n  create-github-release-draft:\n    needs:\n      - process-artifacts\n      - init\n    runs-on: ubuntu-22.04\n    permissions:\n      contents: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Download package artifacts\n        uses: actions/download-artifact@v4\n        with:\n          pattern: package*\n          path: dist\n          merge-multiple: true\n\n      - name: List artifacts\n        run: find dist/\n\n      - name: Verify checksums\n        run: sha256sum --check SHA256SUMS\n        working-directory: dist\n\n      - name: Create GitHub Release\n        env:\n          GH_TOKEN: ${{ github.token }}\n          RELEASE_TAG: ${{ needs.init.outputs.release-tag }}\n        run: gh release create --draft \"${RELEASE_TAG}\" dist/*\n"
  },
  {
    "path": ".gitignore",
    "content": "# Build artifacts\n/build\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n## [0.12.0] - 2024-09-11\n\n### Added\n\n- Use CMake `cxx_std_11` compile feature ([#1135](https://github.com/webview/webview/pull/1135))\n\n### Fixed\n\n- ODR issues caused by functions not being marked with `inline` ([#1138](https://github.com/webview/webview/pull/1138))\n\n### Breaking Changes\n\n- Synchronize CMake alias targets and export names ([#1140](https://github.com/webview/webview/pull/1140))\n\n## [0.11.0] - 2024-08-29\n\n### Added\n\n- New compile-time options for controlling `WEBVIEW_API` ([#893](https://github.com/webview/webview/pull/893))\n- Support for WebKitGTK API 4.1 ([#1022](https://github.com/webview/webview/pull/1022))\n- Support for WebKitGTK API 6.0 and GTK 4 ([#1125](https://github.com/webview/webview/pull/1125))\n- CMake build system ([#1130](https://github.com/webview/webview/pull/1130))\n\n### Changed\n\n- Disable status bar (Windows/WebView2) ([#1028](https://github.com/webview/webview/pull/1028))\n- Reworked handling and reporting of errors ([#1099](https://github.com/webview/webview/pull/1099))\n\n### Breaking Changes\n\n- `WEBVIEW_API` is now `inline` by default for C++ ([#893](https://github.com/webview/webview/pull/893))\n- Treat result of binding function as JSON, not JS ([#1002](https://github.com/webview/webview/pull/1002))\n- App lifecycle separation ([#1005](https://github.com/webview/webview/pull/1005))\n\n## [0.10.0] - 2023-09-16\n\nThis is the first release since the library rewrite by [zserge](https://github.com/zserge) ([#315](https://github.com/webview/webview/pull/315)), and is a necessary one that allows us to prepare for future changes in the library.\n\nDue to the vast amount of contributions that are in this release on top of the changes and removals introduced in the library rewrite, we've picked a few contributions aside from the rewrite that had a significant impact compared to the previous release.\n\n### Added\n\nWindows:\n\n- Microsoft Edge WebView2 backend ([#315](https://github.com/webview/webview/pull/315))\n- Custom WebView2Loader implementation ([#783](https://github.com/webview/webview/pull/783))\n- DPI scaling for Windows 10 and later ([#982](https://github.com/webview/webview/pull/982))\n- Add support for dark title bar on Windows 10 and later ([#996](https://github.com/webview/webview/pull/996))\n\n### Removed\n\n- MSHTML backend ([#315](https://github.com/webview/webview/pull/315))\n- Go binding ([#1009](https://github.com/webview/webview/pull/1009)) — moved to [webview/webview_go](https://github.com/webview/webview_go)\n\n## [0.1.1] - 2020-01-21\n\n## [0.1.0] - 2018-05-09\n\n[unreleased]: https://github.com/webview/webview/compare/0.12.0...HEAD\n[0.12.0]:     https://github.com/webview/webview/compare/0.11.0...0.12.0\n[0.11.0]:     https://github.com/webview/webview/compare/0.10.0...0.11.0\n[0.10.0]:     https://github.com/webview/webview/compare/0.1.1...0.10.0\n[0.1.1]:      https://github.com/webview/webview/compare/0.1.0...0.1.1\n[0.1.0]:      https://github.com/webview/webview/releases/tag/0.1.0\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\n\ninclude(\"${CMAKE_CURRENT_SOURCE_DIR}/cmake/internal.cmake\")\nwebview_extract_version()\n\nproject(\n    webview\n    VERSION \"${WEBVIEW_VERSION_NUMBER}\"\n    DESCRIPTION \"A tiny cross-platform webview library for C/C++ to build modern cross-platform GUIs.\"\n    HOMEPAGE_URL https://github.com/webview/webview)\n\nwebview_init()\n\nif(WEBVIEW_BUILD)\n    add_subdirectory(compatibility)\n\n    if(WEBVIEW_BUILD_TESTS)\n        include(CTest)\n        add_subdirectory(test_driver)\n    endif()\n\n    add_subdirectory(core)\n\n    if(WEBVIEW_BUILD_EXAMPLES)\n        add_subdirectory(examples)\n    endif()\n\n    if(WEBVIEW_BUILD_DOCS)\n        add_subdirectory(docs)\n    endif()\n\n    if(WEBVIEW_INSTALL_TARGETS)\n        webview_install_targets()\n    endif()\n\n    if(WEBVIEW_ENABLE_PACKAGING)\n        add_subdirectory(packaging)\n    endif()\nendif()\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nContributing to the webview project is always welcome! We are especially in need of MacOs developers. Active maintainers who review pull requests and triage issues are listed here.\n- @justjosias\n- @dandeto\n- @nicklasfrahm\n\n### Guidelines for Contributing Examples\n\nAll examples will be held to the same standard as the main codebase.\n\nAdditionally, examples should...\n- Be cross platform except under certain circumstances\n- Highlight a subset of the webview library's API\n- Be well documented\n- Have a simple goal in mind and lack large dependencies\n- Link to external libraries instead of copying them to the webview repo\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Serge Zaitsev\nCopyright (c) 2022 Steffen André Langnes\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MIGRATION.md",
    "content": "# Migration\n\n## v0.11.0 to v0.12.0\n\nSome CMake targets names have been replaced in order to match the exported/installed target names:\n\nOld target         | Replacement\n----------         | -----------\n`webview::headers` | `webview::core`\n`webview::shared`  | `webview::core_shared`\n`webview::static`  | `webview::core_static`\n\n## v0.10.0 to v0.11.0\n\n### New Defaults for `WEBVIEW_API`\n\nLanguage | Old default | New default\n-------- | ----------- | -----------\nC++      | `extern`    | `inline`\nC        | `extern`    | `extern`\n\nIf you relied on the old default being `extern` when using a C++ compiler then you should either define `WEBVIEW_STATIC` or `WEBVIEW_API=extern`.\n\n### Behavior of `webview_return()`\n\n`webview_return()` no longer evaluates the passed-in result as JavaScript but instead parses it as JSON. The new behavior is consistent with the documented behavior while the old behavior wasn't. Use `webview_eval()` if you need to evaluate JavaScript code.\n\n### Application Lifecycle\n\nIf you relied on the library's management of the application lifecycle when passing in an existing window to the library then you should now either manage the lifecycle by yourself or let the library create the window.\n\nSpecific things that are now only done by the library when the window is created for you:\n\nPlatform | What\n-------- | ----\nLinux    | Call to `gtk_init_check()`.\nWindows  | COM initialization and DPI awareness enablement.\n\n## v0.1.1 to v0.10.0\n\n1. Use opaque `webview_t` type instead of `struct webview`. Size, title and URL are controlled via API setter functions. Invoke callback has been replaced with `webview_bind()` and `webview_return()` to make native function bindings inter-operate with JS.\n2. If you have been using simplified `webview()` API to only open a single URL\n   in a webview window - this function has been removed. You now have to create\n   a new webview instance, configure and run it explicitly.\n3. `webview_init()` is replaced by `webview_create()` which creates a new webview instance.\n4. `webview_exit()` has been replaced with more meaningful `webview_destroy()`.\n5. Main UI loop with `webview_loop()` inside has been replaced with `webview_run()` runs infinitely until the webview window is closed.\n6. `webview_terminate()` remains the same.\n7. `webview_dispatch()` remains the same.\n8. `webview_set_title()` remains the same.\n9. `webview_set_color()` has been removed. Use `webview_get_window` and native\n   window APIs to control colors, transparency and other native window\n   properties. At some point these APIs might be brought back.\n10. `webview_set_fullscreen()` has been removed, see above.\n11. `webview_dialog()` has been removed. But I'd like to see it added back as a separate independent module or library.\n12. `webview_eval()` remains the same.\n13. `webview_inject_css()` has been removed. Use `webview_eval()` to create style tag manually.\n14. `webview_debug()` has been removed. Use whatever fits best to your programming language and environment to debug your GUI apps.\n"
  },
  {
    "path": "README.md",
    "content": "# webview\n\n<a href=\"https://discord.gg/24KMecn\" title=\"Join the chat at Discord\"><img src=\"https://assets-global.website-files.com/6257adef93867e50d84d30e2/636e0b5061df29d55a92d945_full_logo_blurple_RGB.svg\" alt=\"Discord\" height=\"20\" /></a>\n[![Build Status](https://img.shields.io/github/actions/workflow/status/webview/webview/ci.yaml?branch=master)](https://github.com/webview/webview/actions)\n\nA tiny cross-platform webview library for C/C++ to build modern cross-platform GUIs.\n\nThe goal of the project is to create a common HTML5 UI abstraction layer for the most widely used platforms.\n\nIt supports two-way JavaScript bindings (to call JavaScript from C/C++ and to call C/C++ from JavaScript).\n\n> [!NOTE]\n> Language binding for Go [has moved][webview_go]. Versions <= 0.1.1 are available in *this* repository.\n\n## Platform Support\n\nPlatform | Technologies\n-------- | ------------\nLinux    | [GTK][gtk], [WebKitGTK][webkitgtk]\nmacOS    | Cocoa, [WebKit][webkit]\nWindows  | [Windows API][win32-api], [WebView2][ms-webview2]\n\n## Documentation\n\nThe most up-to-date documentation is right in the source code. Improving the documentation is a continuous effort and you are more than welcome to contribute.\n\n## Prerequisites\n\nYour compiler must support minimum C++11.\n\nThis project uses CMake and Ninja, and while recommended for your convenience, these tools aren't required for using the library.\n\n### Linux and BSD\n\nThe [GTK][gtk] and [WebKitGTK][webkitgtk] libraries are required for development and distribution. You need to check your package repositories regarding which packages to install.\n\n#### Packages\n\n* Debian:\n  * WebKitGTK 6.0, GTK 4:\n    * Development: `apt install libgtk-4-dev libwebkitgtk-6.0-dev`\n    * Production: `apt install libgtk-4-1 libwebkitgtk-6.0-4`\n  * WebKitGTK 4.1, GTK 3, libsoup 3:\n    * Development: `apt install libgtk-3-dev libwebkit2gtk-4.1-dev`\n    * Production: `apt install libgtk-3-0 libwebkit2gtk-4.1-0`\n  * WebKitGTK 4.0, GTK 3, libsoup 2:\n    * Development: `apt install libgtk-3-dev libwebkit2gtk-4.0-dev`\n    * Production: `apt install libgtk-3-0 libwebkit2gtk-4.0-37`\n* Fedora:\n  * WebKitGTK 6.0, GTK 4:\n    * Development: `dnf install gtk4-devel webkitgtk6.0-devel`\n    * Production: `dnf install gtk4 webkitgtk6.0`\n  * WebKitGTK 4.1, GTK 3, libsoup 3:\n    * Development: `dnf install gtk3-devel webkit2gtk4.1-devel`\n    * Production: `dnf install gtk3 webkit2gtk4.1`\n  * WebKitGTK 4.0, GTK 3, libsoup 2:\n    * Development: `dnf install gtk3-devel webkit2gtk4.0-devel`\n    * Production: `dnf install gtk3 webkit2gtk4.0`\n* FreeBSD:\n  * GTK 4: `pkg install webkit2-gtk4`\n  * GTK 3: `pkg install webkit2-gtk3`\n\n#### Library Dependencies\n\n* Linux:\n  * Use `pkg-config` with `--cflags` and `--libs` to get the compiler/linker options for one of these sets of modules:\n    * `gtk4 webkitgtk-6.0`\n    * `gtk+-3.0 webkit2gtk-4.1`\n    * `gtk+-3.0 webkit2gtk-4.0`\n  * Link libraries: `dl`\n* macOS:\n  * Link frameworks: `WebKit`\n  * Link libraries: `dl`\n* Windows:\n  * [WebView2 from NuGet](https://www.nuget.org/packages/Microsoft.Web.WebView2).\n  * Windows libraries: `advapi32 ole32 shell32 shlwapi user32 version`\n\n#### BSD\n\n* Execution on BSD-based systems may require adding the `wxallowed` option (see [mount(8)](https://man.openbsd.org/mount.8))  to your fstab to bypass [W^X](https://en.wikipedia.org/wiki/W%5EX \"write xor execute\") memory protection for your executable. Please see if it works without disabling this security feature first.\n\n### Windows\n\nYour compiler must support C++14 and we recommend to pair it with an up-to-date Windows 10 SDK.\n\nFor Visual C++ we recommend Visual Studio 2022 or later. There are some [requirements when using MinGW-w64](#mingw-w64-requirements).\n\nDevelopers and end-users must have the [WebView2 runtime][ms-webview2-rt] installed on their system for any version of Windows before Windows 11.\n\n## Getting Started\n\nIf you are a developer of this project then please go to the [development section](#development).\n\nYou will have a working app, but you are encouraged to explore the [available examples][examples].\n\nCreate the following files in a new directory:\n\n`.gitignore`:\n```\n# Build artifacts\n/build\n```\n\n### C++ Example\n\n`CMakeLists.txt`:\n```cmake\ncmake_minimum_required(VERSION 3.16)\nproject(example LANGUAGES CXX)\n\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\")\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\n\ninclude(FetchContent)\n\nFetchContent_Declare(\n    webview\n    GIT_REPOSITORY https://github.com/webview/webview\n    GIT_TAG 0.12.0)\nFetchContent_MakeAvailable(webview)\n\nadd_executable(example WIN32)\ntarget_sources(example PRIVATE main.cc)\ntarget_link_libraries(example PRIVATE webview::core)\n```\n\n`main.cc`:\n```cpp\n#include \"webview/webview.h\"\n\n#include <iostream>\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,\n                   LPSTR /*lpCmdLine*/, int /*nCmdShow*/) {\n#else\nint main() {\n#endif\n  try {\n    webview::webview w(false, nullptr);\n    w.set_title(\"Basic Example\");\n    w.set_size(480, 320, WEBVIEW_HINT_NONE);\n    w.set_html(\"Thanks for using webview!\");\n    w.run();\n  } catch (const webview::exception &e) {\n    std::cerr << e.what() << '\\n';\n    return 1;\n  }\n\n  return 0;\n}\n```\n\n### C Example\n\n`CMakeLists.txt`:\n```cmake\ncmake_minimum_required(VERSION 3.16)\nproject(example LANGUAGES C CXX)\n\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\")\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\n\ninclude(FetchContent)\n\nFetchContent_Declare(\n    webview\n    GIT_REPOSITORY https://github.com/webview/webview\n    GIT_TAG 0.12.0)\nFetchContent_MakeAvailable(webview)\n\nadd_executable(example WIN32)\ntarget_sources(example PRIVATE main.c)\ntarget_link_libraries(example PRIVATE webview::core_static)\n```\n\n`main.c`:\n```cpp\n#include \"webview/webview.h\"\n#include <stddef.h>\n\n#ifdef _WIN32\n#include <windows.h>\n#endif\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,\n                   int nCmdShow) {\n  (void)hInst;\n  (void)hPrevInst;\n  (void)lpCmdLine;\n  (void)nCmdShow;\n#else\nint main(void) {\n#endif\n  webview_t w = webview_create(0, NULL);\n  webview_set_title(w, \"Basic Example\");\n  webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);\n  webview_set_html(w, \"Thanks for using webview!\");\n  webview_run(w);\n  webview_destroy(w);\n  return 0;\n}\n```\n\n### Building the Example\n\nBuild the project:\n\n```sh\ncmake -G Ninja -B build -S . -D CMAKE_BUILD_TYPE=Release\ncmake --build build\n```\n\nFind the executable in the `build/bin` directory.\n\n### Building Amalgamated Library\n\nAn amalgamated library can be built when building the project using CMake, or the `amalgamate.py` script can be invoked directly.\n\nThe latter is described below.\n\n```sh\npython3 scripts/amalgamate/amalgamate.py --base core --search include --output webview_amalgamation.h src\n```\n\nSee `python3 scripts/amalgamate/amalgamate.py --help` for script usage.\n\n### Non-CMake Usage\n\nHere's an example for invoking GCC/Clang-like compilers directly. Use the `main.cc` file from the previous example.\n\nPlace either the amalgamated `webview.h` header or all of the individual files into `libs/webview`, and `WebView2.h` from [MS WebView2][ms-webview2-sdk] into `libs`.\n\nBuild the project on your chosen platform.\n\n<details>\n  <summary>macOS</summary>\n  <pre><code>c++ main.cc -O2 --std=c++11 -Ilibs -framework WebKit -ldl -o example</code></pre>\n</details>\n\n<details>\n  <summary>Linux</summary>\n  <pre><code>c++ main.cc -O2 --std=c++11 -Ilibs $(pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.1) -ldl -o example</code></pre>\n</details>\n\n<details>\n  <summary>Windows</summary>\n  <pre><code>c++ main.cc -O2 --std=c++14 -static -mwindows -Ilibs -ladvapi32 -lole32 -lshell32 -lshlwapi -luser32 -lversion -o example</code></pre>\n</details>\n\n## Customization\n\n### CMake Targets\n\nThe following CMake targets are available:\n\nName                   | Description\n----                   | -----------\n`webview::core`        | Headers for C++.\n`webview::core_shared` | Shared library for C.\n`webview::core_static` | Static library for C.\n\nSpecial targets for on-demand checks and related tasks:\n\nName                   | Description\n----                   | -----------\n`webview_format_check` | Check files with clang-format.\n`webview_reformat`     | Reformat files with clang-format.\n\n### CMake Options\n\nThe following boolean options can be used when building the webview project standalone or when building it as part of your project (e.g. with FetchContent).\n\nOption                            | Description\n------                            | -----------\n`WEBVIEW_BUILD`                   | Enable building\n`WEBVIEW_BUILD_AMALGAMATION`      | Build amalgamated library\n`WEBVIEW_BUILD_DOCS`              | Build documentation\n`WEBVIEW_BUILD_EXAMPLES`          | Build examples\n`WEBVIEW_BUILD_SHARED_LIBRARY`    | Build shared libraries\n`WEBVIEW_BUILD_STATIC_LIBRARY`    | Build static libraries\n`WEBVIEW_BUILD_TESTS`             | Build tests\n`WEBVIEW_ENABLE_CHECKS`           | Enable checks\n`WEBVIEW_ENABLE_CLANG_FORMAT`     | Enable clang-format\n`WEBVIEW_ENABLE_CLANG_TIDY`       | Enable clang-tidy\n`WEBVIEW_ENABLE_PACKAGING`        | Enable packaging\n`WEBVIEW_INSTALL_DOCS`            | Install documentation\n`WEBVIEW_INSTALL_TARGETS`         | Install targets\n`WEBVIEW_IS_CI`                   | Initialized by the `CI` environment variable\n`WEBVIEW_PACKAGE_AMALGAMATION`    | Package amalgamated library\n`WEBVIEW_PACKAGE_DOCS`            | Package documentation\n`WEBVIEW_PACKAGE_HEADERS`         | Package headers\n`WEBVIEW_PACKAGE_LIB`             | Package compiled libraries\n`WEBVIEW_STRICT_CHECKS`           | Make checks strict\n`WEBVIEW_STRICT_CLANG_FORMAT`     | Make clang-format check strict\n`WEBVIEW_STRICT_CLANG_TIDY`       | Make clang-tidy check strict\n`WEBVIEW_USE_COMPAT_MINGW`        | Use compatibility helper for MinGW\n`WEBVIEW_USE_STATIC_MSVC_RUNTIME` | Use static runtime library (MSVC)\n\n> [!NOTE]\n> Checks are *enabled* by default, but aren't *enforced* by default for local development (controlled by the `WEBVIEW_IS_CI` option).\n\nNon-boolean options:\n\nOption                            | Description\n------                            | -----------\n`WEBVIEW_CLANG_FORMAT_EXE`        | Path of the `clang-format` executable.\n`WEBVIEW_CLANG_TIDY_EXE`          | Path of the `clang-tidy` executable.\n\n### Package Consumer Options\n\nThese options can be used when when using the webview CMake package.\n\n#### Linux-specific Options\n\nOption                          | Description\n------                          | -----------\n`WEBVIEW_WEBKITGTK_API`         | WebKitGTK API to interface with, e.g. `6.0`, `4.1` (recommended) or `4.0`. This will also automatically decide the GTK version. Uses the latest recommended API by default if available, or the latest known and available API. Note that there can be major differences between API versions that can affect feature availability. See webview API documentation for details on feature availability.\n\n#### Windows-specific Options\n\nOption                          | Description\n------                          | -----------\n`WEBVIEW_MSWEBVIEW2_VERSION`    | MS WebView2 version, e.g. `1.0.1150.38`.\n`WEBVIEW_USE_BUILTIN_MSWEBVIEW2`| Use built-in MS WebView2.\n\n### Compile-time Options\n\nThese options can be specified as preprocessor macros to modify the build, but are not needed when using CMake.\n\n#### C API Linkage\n\nName                   | Description\n----                   | -----------\n`WEBVIEW_API`          | Controls C API linkage, symbol visibility and whether it's a shared library. By default this is `inline` for C++ and `extern` for C.\n`WEBVIEW_BUILD_SHARED` | Modifies `WEBVIEW_API` for building a shared library.\n`WEBVIEW_SHARED`       | Modifies `WEBVIEW_API` for using a shared library.\n`WEBVIEW_STATIC`       | Modifies `WEBVIEW_API` for building or using a static library.\n\n#### Backend Selection\n\nName                   | Description\n----                   | -----------\n`WEBVIEW_GTK`          | Compile the GTK/WebKitGTK backend.\n`WEBVIEW_COCOA`        | Compile the Cocoa/WebKit backend.\n`WEBVIEW_EDGE`         | Compile the Win32/WebView2 backend.\n\n#### Windows-specific Options\n\nOption                            | Description\n------                            | -----------\n`WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` | Enables (`1`) or disables (`0`) the built-in implementation of the WebView2 loader. Enabling this avoids the need for `WebView2Loader.dll` but if the DLL is present then the DLL takes priority. This option is enabled by default.\n`WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK`| Enables (`1`) or disables (`0`) explicit linking of `WebView2Loader.dll`. Enabling this avoids the need for import libraries (`*.lib`). This option is enabled by default if `WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` is enabled.\n\n## MinGW-w64 Requirements\n\nIn order to build this library using MinGW-w64 on Windows then it must support C++14 and have an up-to-date Windows SDK.\n\nDistributions that are known to be compatible:\n\n* [LLVM MinGW](https://github.com/mstorsjo/llvm-mingw)\n* [MSYS2](https://www.msys2.org/)\n* [WinLibs](https://winlibs.com/)\n\n## MS WebView2 Loader\n\nLinking the WebView2 loader part of the Microsoft WebView2 SDK is not a hard requirement when using our webview library, and neither is distributing `WebView2Loader.dll` with your app.\n\nIf, however, `WebView2Loader.dll` is loadable at runtime, e.g. from the executable's directory, then it will be used; otherwise our minimalistic implementation will be used instead.\n\nShould you wish to use the official loader then remember to distribute it along with your app unless you link it statically. Linking it statically is possible with Visual C++ but not MinGW-w64.\n\nHere are some of the noteworthy ways our implementation of the loader differs from the official implementation:\n\n* Does not support configuring WebView2 using environment variables such as `WEBVIEW2_BROWSER_EXECUTABLE_FOLDER`.\n* Microsoft Edge Insider (preview) channels are not supported.\n\n[Customization options](#Customization) can be used to change how the library integrates the WebView2 loader.\n\n## Thread Safety\n\nSince library functions generally do not have thread safety guarantees, `webview_dispatch()` (C) / `webview::dispatch()` (C++) can be used to schedule code to execute on the main/GUI thread and thereby make that execution safe in multi-threaded applications.\n\n`webview_return()` (C) / `webview::resolve()` (C++) uses `*dispatch()` internally and is therefore safe to call from another thread.\n\nThe main/GUI thread should be the thread that calls `webview_run()` (C) / `webview::run()` (C++).\n\n## Development\n\nThis project uses the CMake build system.\n\n### Development Dependencies\n\nIn addition to the dependencies mentioned earlier in this document for developing *with* the webview library, the following are used during development *of* the webview library.\n\n* Amalgamation:\n  * Python >= 3.9\n* Checks:\n  * `clang-format`\n  * `clang-tidy`\n* Documentation:\n  * Doxygen\n  * Graphvis\n\n### Building\n\n```sh\ncmake -G \"Ninja Multi-Config\" -B build -S .\ncmake --build build --config CONFIG\n```\n\nReplace `CONFIG` with one of `Debug`, `Release`, or `Profile`. Use `Profile` to enable code coverage (GCC/Clang).\n\nRun tests:\n\n```sh\nctest --test-dir build --build-config CONFIG\n```\n\nGenerate test coverage report:\n\n```sh\ngcovr\n```\n\nFind the coverage report in `build/coverage`.\n\n### Packaging\n\nRun this after building the `Debug` and `Release` configs of the project:\n\n```sh\ncd build\ncpack -G External -C \"Debug;Release\" --config CPackConfig.cmake\n```\n\n### Cross-compilation\n\nSee CMake toolchain files in the `cmake/toolchains` directory.\n\nFor example, this targets Windows x64 on Linux with POSIX threads:\n\n```sh\ncmake -G \"Ninja Multi-Config\" -B build -S . -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64-w64-mingw32.cmake -D WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX=-posix\ncmake --build build --config CONFIG\n```\n\n## Limitations\n\n### Browser Features\n\nSince a browser engine is not a full web browser it may not support every feature you may expect from a browser. If you find that a feature does not work as expected then please consult with the browser engine's documentation and [open an issue][issues-new] if you think that the library should support it.\n\nFor example, the library does not attempt to support user interaction features like `alert()`, `confirm()` and `prompt()` and other non-essential features like `console.log()`.\n\n## Bindings\n\nLanguage    | Project\n----------  | -------\nAda         | [thechampagne/webview-ada](https://github.com/thechampagne/webview-ada)\nBun         | [tr1ckydev/webview-bun](https://github.com/tr1ckydev/webview-bun)\nC#          | [webview/webview_csharp](https://github.com/webview/webview_csharp)\nC3          | [thechampagne/webview-c3](https://github.com/thechampagne/webview-c3)\nCrystal     | [naqvis/webview](https://github.com/naqvis/webview)\nD           | [thechampagne/webview-d](https://github.com/thechampagne/webview-d), [ronnie-w/webviewd](https://github.com/ronnie-w/webviewd)\nDeno        | [webview/webview_deno](https://github.com/webview/webview_deno)\nGo          | [webview/webview_go][webview_go]\nHarbour     | [EricLendvai/Harbour_WebView](https://github.com/EricLendvai/Harbour_WebView)\nHaskell     | [lettier/webviewhs](https://github.com/lettier/webviewhs)\nJanet       | [janet-lang/webview](https://github.com/janet-lang/webview)\nJava        | [webview/webview_java](https://github.com/webview/webview_java)\nKotlin      | [Winterreisender/webviewko](https://github.com/Winterreisender/webviewko)\nMoonBit     | [justjavac/moonbit-webview](https://github.com/justjavac/moonbit-webview)\nNim         | [oskca/webview](https://github.com/oskca/webview), [neroist/webview](https://github.com/neroist/webview)\nNode.js     | [Winterreisender/webview-nodejs](https://github.com/Winterreisender/webview-nodejs)\nOdin        | [thechampagne/webview-odin](https://github.com/thechampagne/webview-odin)\nPascal      | [PierceNg/fpwebview](http://github.com/PierceNg/fpwebview)\nPython      | [congzhangzh/webview_python](https://github.com/congzhangzh/webview_python),[zserge/webview-python](https://github.com/zserge/webview-python)\nPHP         | [0hr/php-webview](https://github.com/0hr/php-webview), [KingBes/pebview](https://github.com/KingBes/pebview), [happystraw/php-ext-webview](https://github.com/happystraw/php-ext-webview)\nRing        | [ysdragon/webview](https://github.com/ysdragon/webview)\nRuby        | [Maaarcocr/webview_ruby](https://github.com/Maaarcocr/webview_ruby)\nRust        | [Boscop/web-view](https://github.com/Boscop/web-view)\nSwift       | [jakenvac/SwiftWebview](https://github.com/jakenvac/SwiftWebview)\nV           | [malisipi/mui](https://github.com/malisipi/mui/tree/main/webview), [ttytm/webview](https://github.com/ttytm/webview)\nVala        | [taozuhong/webview-vala](https://github.com/taozuhong/webview-vala)\nZig         | [thechampagne/webview-zig](https://github.com/thechampagne/webview-zig), [happystraw/zig-webview](https://github.com/happystraw/zig-webview)\n\nIf you wish to add bindings to the list, feel free to submit a pull request or [open an issue][issues-new].\n\n## Generating Bindings\n\nYou can generate bindings for the library by yourself using the included SWIG interface (`webview.i`).\n\nHere are some examples to get you started. Unix-style command lines are used for conciseness.\n\n```sh\nmkdir -p build/bindings/{python,csharp,java,ruby}\nswig -c++ -python -outdir build/bindings/python -o build/bindings/python/python_wrap.cpp webview.i\nswig -c++ -csharp -outdir build/bindings/csharp -o build/bindings/csharp/csharp_wrap.cpp webview.i\nswig -c++ -java -outdir build/bindings/java -o build/bindings/java/java_wrap.cpp webview.i\nswig -c++ -ruby -outdir build/bindings/ruby -o build/bindings/ruby/ruby_wrap.cpp webview.i\n```\n\n## License\n\nCode is distributed under MIT license, feel free to use it in your proprietary projects as well.\n\n[examples]:          https://github.com/webview/webview/tree/master/examples\n[gtk]:               https://gtk.org/\n[issues]:            https://github.com/webview/docs/issues\n[issues-new]:        https://github.com/webview/webview/issues/new\n[webkit]:            https://webkit.org/\n[webkitgtk]:         https://webkitgtk.org/\n[webview]:           https://github.com/webview/webview\n[webview_go]:        https://github.com/webview/webview_go\n[webview.dev]:       https://webview.dev\n[ms-webview2]:       https://developer.microsoft.com/en-us/microsoft-edge/webview2/\n[ms-webview2-sdk]:   https://www.nuget.org/packages/Microsoft.Web.WebView2\n[ms-webview2-rt]:    https://developer.microsoft.com/en-us/microsoft-edge/webview2/\n[win32-api]:         https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list\n"
  },
  {
    "path": "cmake/clang_format.cmake",
    "content": "file(TO_CMAKE_PATH \"${BINARY_DIR}\" BINARY_DIR)\nfile(TO_CMAKE_PATH \"${SOURCE_DIR}\" SOURCE_DIR)\n\nfile(GLOB_RECURSE TEMP_FILES\n    ${SOURCE_DIR}/*.h\n    ${SOURCE_DIR}/*.hh\n    ${SOURCE_DIR}/*.hpp\n    ${SOURCE_DIR}/*.hxx\n    ${SOURCE_DIR}/*.c\n    ${SOURCE_DIR}/*.cc\n    ${SOURCE_DIR}/*.cpp\n    ${SOURCE_DIR}/*.cxx)\n\nset(FILES)\nforeach(FILE IN LISTS TEMP_FILES)\n    file(TO_CMAKE_PATH \"${FILE}\" FILE)\n    if(NOT FILE MATCHES \"^${BINARY_DIR}(/|$)\")\n        list(APPEND FILES \"${FILE}\")\n    endif()\nendforeach()\n\nif(CMD STREQUAL \"check\")\n    set(ARGS \"--dry-run\")\nelseif(CMD STREQUAL \"reformat\")\n    set(ARGS \"-i\")\nendif()\n\nif(STRICT)\n    list(APPEND ARGS \"--Werror\")\nendif()\n\nexecute_process(COMMAND \"${CLANG_FORMAT_EXE}\" ${ARGS} ${FILES}\n    RESULT_VARIABLE RESULT)\n\nif(NOT RESULT EQUAL 0 AND (STRICT OR NOT RESULT EQUAL 1))\n    message(FATAL_ERROR \"clang-format check failed.\")\nendif()\n"
  },
  {
    "path": "cmake/extract_version.cmake",
    "content": "# Extracts the library's version number and prints it to stdout.\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/internal.cmake\")\nwebview_extract_version()\n# Need this workaround because message() prints to stderr\nexecute_process(COMMAND ${CMAKE_COMMAND} -E echo \"${WEBVIEW_VERSION}\")\n"
  },
  {
    "path": "cmake/internal.cmake",
    "content": "set(WEBVIEW_CURRENT_CMAKE_DIR \"${CMAKE_CURRENT_LIST_DIR}\")\ninclude(\"${WEBVIEW_CURRENT_CMAKE_DIR}/webview.cmake\")\n\n# Needed when we need the project directory before calling project()\nset(WEBVIEW_ROOT_DIR \"${WEBVIEW_CURRENT_CMAKE_DIR}/..\")\n\nmacro(webview_init)\n    include(CheckCXXSourceCompiles)\n    include(CMakeDependentOption)\n    include(CMakePackageConfigHelpers)\n    include(GNUInstallDirs)\n\n    list(APPEND CMAKE_MODULE_PATH \"${WEBVIEW_CURRENT_CMAKE_DIR}/modules\")\n\n    enable_language(C CXX)\n\n    webview_options()\n    webview_internal_options()\n\n    # Version 0.x of the library can't guarantee backward compatibility.\n    if(WEBVIEW_VERSION_NUMBER VERSION_LESS 1.0)\n        set(WEBVIEW_VERSION_COMPATIBILITY \"${WEBVIEW_VERSION_MAJOR}.${WEBVIEW_VERSION_MINOR}\")\n    else()\n        set(WEBVIEW_VERSION_COMPATIBILITY \"${WEBVIEW_VERSION_NUMBER}\")\n    endif()\n\n    # Hide symbols by default\n    set(CMAKE_CXX_VISIBILITY_PRESET hidden)\n    set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)\n\n    # Use debug postfix to separate debug/release binaries for the library\n    set(CMAKE_DEBUG_POSTFIX d)\n\n    if(WEBVIEW_IS_TOP_LEVEL_BUILD)\n        # Add custom build types\n        if(CMAKE_CONFIGURATION_TYPES)\n            list(APPEND CMAKE_CONFIGURATION_TYPES Profile)\n            list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)\n            set(CMAKE_CONFIGURATION_TYPES \"${CMAKE_CONFIGURATION_TYPES}\" CACHE STRING \"\" FORCE)\n        endif()\n\n        # Use custom compiler/linker flags for the \"Profile\" build type\n        if((CMAKE_C_COMPILER_ID MATCHES \"((^GNU)|Clang)$\") AND (CMAKE_CXX_COMPILER_ID MATCHES \"((^GNU)|Clang)$\"))\n            set(CMAKE_C_FLAGS_PROFILE \"-g -O0 -fprofile-arcs -ftest-coverage\")\n            set(CMAKE_CXX_FLAGS_PROFILE \"-g -O0 -fprofile-arcs -ftest-coverage\")\n            set(CMAKE_EXE_LINKER_FLAGS_PROFILE \"-fprofile-arcs\")\n            set(CMAKE_SHARED_LINKER_FLAGS_PROFILE \"-fprofile-arcs\")\n        elseif(MSVC)\n            # MSVC isn't supported but warnings are emitted if these variables are undefined\n            set(CMAKE_C_FLAGS_PROFILE \"/Od\")\n            set(CMAKE_CXX_FLAGS_PROFILE \"/Od\")\n            set(CMAKE_EXE_LINKER_FLAGS_PROFILE \"\")\n            set(CMAKE_SHARED_LINKER_FLAGS_PROFILE \"\")\n        endif()\n\n        # Default language standards\n        # All of CMAKE_<LANG>_STANDARD, CMAKE_<LANG>_REQUIRED and CMAKE_<LANG>_EXTENSIONS must be set\n        # Note that we also use the cxx_std_11 compile feature for consumers\n        set(CMAKE_C_STANDARD 99 CACHE STRING \"\")\n        set(CMAKE_C_STANDARD_REQUIRED YES)\n        set(CMAKE_C_EXTENSIONS NO)\n        set(CMAKE_CXX_STANDARD 11 CACHE STRING \"\")\n        set(CMAKE_CXX_STANDARD_REQUIRED YES)\n        set(CMAKE_CXX_EXTENSIONS NO)\n\n        # Enable output of compile commands\n        set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n        # Enable compile warnings\n        if(MSVC)\n            add_compile_options(/W4)\n        else()\n            add_compile_options(-Wall -Wextra -Wpedantic)\n        endif()\n\n        # Set default build type for single-config generators\n        get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)\n        if(NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)\n            set(CMAKE_BUILD_TYPE Release CACHE STRING \"\" FORCE)\n        endif()\n\n        if(WEBVIEW_USE_STATIC_MSVC_RUNTIME AND MSVC AND NOT CMAKE_MSVC_RUNTIME_LIBRARY)\n            # Use static MSVC runtime library\n            set(CMAKE_MSVC_RUNTIME_LIBRARY \"MultiThreaded$<$<CONFIG:Debug>:Debug>\")\n        endif()\n\n        webview_set_install_rpath()\n\n        if(WEBVIEW_ENABLE_CHECKS AND WEBVIEW_ENABLE_CLANG_FORMAT)\n            # Allow skipping clang-format outside of CI environment\n\n            webview_find_clang_format(${WEBVIEW_IS_CI})\n\n            if(WEBVIEW_CLANG_FORMAT_FOUND)\n                add_custom_target(webview_format_check ALL\n                    COMMAND ${CMAKE_COMMAND}\n                        -D CMD=check\n                        -D \"BINARY_DIR=${PROJECT_BINARY_DIR}\"\n                        -D \"SOURCE_DIR=${PROJECT_SOURCE_DIR}\"\n                        -D \"CLANG_FORMAT_EXE=${WEBVIEW_CLANG_FORMAT_EXE}\"\n                        -D \"STRICT=$<AND:$<BOOL:${WEBVIEW_STRICT_CHECKS}>,$<BOOL:${WEBVIEW_STRICT_CLANG_FORMAT}>>\"\n                        -P \"${WEBVIEW_CURRENT_CMAKE_DIR}/clang_format.cmake\"\n                    COMMENT \"Checking files with clang-format...\"\n                    VERBATIM)\n                add_custom_target(webview_reformat\n                    COMMAND ${CMAKE_COMMAND}\n                        -D CMD=reformat\n                        -D \"BINARY_DIR=${PROJECT_BINARY_DIR}\"\n                        -D \"SOURCE_DIR=${PROJECT_SOURCE_DIR}\"\n                        -D \"CLANG_FORMAT_EXE=${WEBVIEW_CLANG_FORMAT_EXE}\"\n                        -P \"${WEBVIEW_CURRENT_CMAKE_DIR}/clang_format.cmake\"\n                    COMMENT \"Reformatting files with clang-format...\"\n                    VERBATIM)\n            else()\n                message(WARNING \"Skipping clang-format checks as clang-format was not found\")\n            endif()\n        endif()\n\n        if(WEBVIEW_ENABLE_CHECKS AND WEBVIEW_ENABLE_CLANG_TIDY)\n            if((CMAKE_C_COMPILER_ID MATCHES \"Clang$\") AND (CMAKE_CXX_COMPILER_ID MATCHES \"Clang$\"))\n                # Allow skipping clang-tidy outside of CI environment\n\n                webview_find_clang_tidy(${WEBVIEW_IS_CI})\n\n                if(WEBVIEW_CLANG_TIDY_FOUND)\n                    set(WEBVIEW_CLANG_TIDY_ARGS)\n                    if(WEBVIEW_STRICT_CHECKS AND WEBVIEW_STRICT_CLANG_TIDY)\n                        list(APPEND WEBVIEW_CLANG_TIDY_ARGS \"--warnings-as-errors=*\")\n                    endif()\n\n                    set(CMAKE_C_CLANG_TIDY \"${WEBVIEW_CLANG_TIDY_EXE}\" ${WEBVIEW_CLANG_TIDY_ARGS})\n                    set(CMAKE_CXX_CLANG_TIDY \"${WEBVIEW_CLANG_TIDY_EXE}\" ${WEBVIEW_CLANG_TIDY_ARGS})\n                else()\n                    message(WARNING \"Skipping clang-tidy checks as clang-tidy was not found: ${WEBVIEW_CLANG_TIDY_EXE_HINT}\")\n                endif()\n            else()\n                # Skip check when clang isn't used with clang-tidy to avoid errors due to unsupported compiler flags\n                # such as -fno-keep-inline-dllexport (tested GCC 14, Clang-Tidy 18)\n                message(WARNING \"Skipping clang-tidy checks with non-clang compiler.\")\n            endif()\n        endif()\n    endif()\n\n    if(WEBVIEW_BUILD)\n        webview_find_dependencies()\n    endif()\nendmacro()\n\nfunction(webview_find_clang_format REQUIRED)\n    if(WEBVIEW_CLANG_FORMAT_EXE)\n        set(WEBVIEW_CLANG_FORMAT_FOUND TRUE PARENT_SCOPE)\n        return()\n    endif()\n    set(CLANG_FORMAT_EXE_HINT \"clang-format\")\n    set(FIND_ARGS WEBVIEW_CLANG_FORMAT_EXE \"${CLANG_FORMAT_EXE_HINT}\")\n    if(REQUIRED)\n        list(APPEND FIND_ARGS REQUIRED)\n    endif()\n    find_program(${FIND_ARGS})\n    if(WEBVIEW_CLANG_FORMAT_EXE)\n        set(WEBVIEW_CLANG_FORMAT_FOUND TRUE PARENT_SCOPE)\n    else()\n        set(WEBVIEW_CLANG_FORMAT_FOUND FALSE PARENT_SCOPE)\n    endif()\nendfunction()\n\nfunction(webview_find_clang_tidy REQUIRED)\n    if(WEBVIEW_CLANG_TIDY_EXE)\n        set(WEBVIEW_CLANG_TIDY_FOUND TRUE PARENT_SCOPE)\n        return()\n    endif()\n    # Using WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX here because we pair clang-tidy with the clang compiler\n    set(WEBVIEW_CLANG_TIDY_EXE_HINT \"clang-tidy${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n    set(FIND_ARGS WEBVIEW_CLANG_TIDY_EXE \"${WEBVIEW_CLANG_TIDY_EXE_HINT}\")\n    if(REQUIRED)\n        list(APPEND FIND_ARGS REQUIRED)\n    endif()\n    find_program(${FIND_ARGS})\n    if(WEBVIEW_CLANG_TIDY_EXE)\n        set(WEBVIEW_CLANG_TIDY_FOUND TRUE PARENT_SCOPE)\n    else()\n        set(WEBVIEW_CLANG_TIDY_FOUND FALSE PARENT_SCOPE)\n    endif()\nendfunction()\n\nfunction(webview_find_doxygen REQUIRED)\n    if(REQUIRED)\n        list(APPEND FIND_ARGS REQUIRED)\n    endif()\n    list(APPEND FIND_ARGS COMPONENTS dot)\n    find_package(Doxygen ${FIND_ARGS})\n    set(Doxygen_FOUND \"${Doxygen_FOUND}\" PARENT_SCOPE)\n    set(Doxygen_FOUND_EXECUTABLE \"${Doxygen_FOUND_EXECUTABLE}\" PARENT_SCOPE)\nendfunction()\n\nfunction(webview_find_python3 REQUIRED)\n    if(REQUIRED)\n        list(APPEND FIND_ARGS REQUIRED)\n    endif()\n    find_package(Python3 ${FIND_ARGS})\n    set(Python3_FOUND \"${Python3_FOUND}\" PARENT_SCOPE)\n    set(Python3_EXECUTABLE \"${Python3_EXECUTABLE}\" PARENT_SCOPE)\nendfunction()\n\nmacro(webview_extract_version)\n    file(READ \"${WEBVIEW_ROOT_DIR}/core/include/webview/version.h\" WEBVIEW_H_CONTENT)\n\n    if(NOT DEFINED WEBVIEW_VERSION_MAJOR)\n        string(REGEX MATCH \"#define WEBVIEW_VERSION_MAJOR ([0-9]+)\" WEBVIEW_VERSION_MAJOR_MATCH \"${WEBVIEW_H_CONTENT}\")\n        set(WEBVIEW_VERSION_MAJOR \"${CMAKE_MATCH_1}\")\n    endif()\n\n    if(NOT DEFINED WEBVIEW_VERSION_MINOR)\n        string(REGEX MATCH \"#define WEBVIEW_VERSION_MINOR ([0-9]+)\" WEBVIEW_VERSION_MINOR_MATCH \"${WEBVIEW_H_CONTENT}\")\n        set(WEBVIEW_VERSION_MINOR \"${CMAKE_MATCH_1}\")\n    endif()\n\n    if(NOT DEFINED WEBVIEW_VERSION_PATCH)\n        string(REGEX MATCH \"#define WEBVIEW_VERSION_PATCH ([0-9]+)\" WEBVIEW_VERSION_PATCH_MATCH \"${WEBVIEW_H_CONTENT}\")\n        set(WEBVIEW_VERSION_PATCH \"${CMAKE_MATCH_1}\")\n    endif()\n\n    if(NOT DEFINED WEBVIEW_VERSION_PRE_RELEASE)\n        string(REGEX MATCH \"#define WEBVIEW_VERSION_PRE_RELEASE \\\"([^\\\"]*)\\\"\" WEBVIEW_VERSION_PRE_RELEASE_MATCH \"${WEBVIEW_H_CONTENT}\")\n        set(WEBVIEW_VERSION_PRE_RELEASE \"${CMAKE_MATCH_1}\")\n    endif()\n\n    if(NOT DEFINED WEBVIEW_VERSION_BUILD_METADATA)\n        string(REGEX MATCH \"#define WEBVIEW_VERSION_BUILD_METADATA \\\"([^\\\"]*)\\\"\" WEBVIEW_VERSION_BUILD_METADATA_MATCH \"${WEBVIEW_H_CONTENT}\")\n        set(WEBVIEW_VERSION_BUILD_METADATA \"${CMAKE_MATCH_1}\")\n    endif()\n\n    set(WEBVIEW_VERSION_NUMBER \"${WEBVIEW_VERSION_MAJOR}.${WEBVIEW_VERSION_MINOR}.${WEBVIEW_VERSION_PATCH}\")\n    set(WEBVIEW_VERSION \"${WEBVIEW_VERSION_NUMBER}${WEBVIEW_VERSION_PRE_RELEASE}${WEBVIEW_VERSION_BUILD_METADATA}\")\nendmacro()\n\nmacro(webview_install_targets)\n    # Install headers\n    install(DIRECTORY \"${WEBVIEW_ROOT_DIR}/core/include/webview\"\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\"\n        COMPONENT webview_headers)\n\n    # Install modules\n    install(DIRECTORY \"${WEBVIEW_CURRENT_CMAKE_DIR}/modules\"\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/webview\"\n        COMPONENT webview_cmake)\n\n    # Install targets\n    list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_headers)\n\n    if(WEBVIEW_BUILD_SHARED_LIBRARY)\n        list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_shared)\n    endif()\n\n    if(WEBVIEW_BUILD_STATIC_LIBRARY)\n        list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_static)\n    endif()\n\n    if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\" AND WEBVIEW_USE_COMPAT_MINGW)\n        list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_compat_mingw)\n    endif()\n\n    install(TARGETS ${WEBVIEW_INSTALL_TARGET_NAMES}\n        COMPONENT webview_libraries_runtime_release\n        CONFIGURATIONS Release\n        RUNTIME\n            DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        LIBRARY\n            DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n            NAMELINK_COMPONENT webview_trash\n        ARCHIVE\n            DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n            COMPONENT webview_trash)\n\n    install(TARGETS ${WEBVIEW_INSTALL_TARGET_NAMES}\n        EXPORT webview_targets\n        COMPONENT webview_libraries\n        RUNTIME\n            DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        LIBRARY\n            DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        ARCHIVE\n            DESTINATION \"${CMAKE_INSTALL_LIBDIR}\")\n\n    install(EXPORT webview_targets\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/webview\"\n        NAMESPACE webview::\n        FILE webview-targets.cmake\n        COMPONENT webview_cmake)\n\n    export(EXPORT webview_targets FILE \"${CMAKE_CURRENT_BINARY_DIR}/webview-targets.cmake\")\n\n    # Install package config\n    configure_package_config_file(\n        \"${WEBVIEW_CURRENT_CMAKE_DIR}/webview-config.cmake.in\"\n        \"${CMAKE_CURRENT_BINARY_DIR}/webview-config.cmake\"\n        INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/webview\"\n        NO_SET_AND_CHECK_MACRO\n        NO_CHECK_REQUIRED_COMPONENTS_MACRO)\n\n    write_basic_package_version_file(\n        \"${CMAKE_CURRENT_BINARY_DIR}/webview-config-version.cmake\"\n        VERSION \"${WEBVIEW_VERSION_COMPATIBILITY}\"\n        COMPATIBILITY SameMinorVersion)\n\n    install(\n        FILES\n            \"${WEBVIEW_CURRENT_CMAKE_DIR}/webview.cmake\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/webview-config.cmake\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/webview-config-version.cmake\"\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/webview\"\n        COMPONENT webview_cmake)\nendmacro()\n\nmacro(webview_internal_options)\n    if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n        set(WEBVIEW_IS_TOP_LEVEL_BUILD TRUE)\n    endif()\n\n    if(NOT DEFINED WEBVIEW_IS_CI)\n        set(WEBVIEW_IS_CI FALSE)\n        if(\"$ENV{CI}\" MATCHES \"^(1|true|TRUE)$\")\n            set(WEBVIEW_IS_CI TRUE)\n        endif()\n    endif()\n\n    option(WEBVIEW_BUILD \"Enable building\" ON)\n    cmake_dependent_option(WEBVIEW_BUILD_AMALGAMATION \"Build amalgamated library\" ON \"WEBVIEW_BUILD;WEBVIEW_IS_TOP_LEVEL_BUILD\" OFF)\n    option(WEBVIEW_BUILD_DOCS \"Build documentation\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_BUILD_TESTS \"Build tests\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_BUILD_EXAMPLES \"Build examples\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_INSTALL_DOCS \"Install documentation\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_INSTALL_TARGETS \"Install targets\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_BUILD_SHARED_LIBRARY \"Build shared libraries\" ON)\n    option(WEBVIEW_BUILD_STATIC_LIBRARY \"Build static libraries\" ON)\n    option(WEBVIEW_USE_COMPAT_MINGW \"Use compatibility helper for MinGW\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_USE_STATIC_MSVC_RUNTIME \"Use static runtime library (MSVC)\" OFF)\n    option(WEBVIEW_ENABLE_CHECKS \"Enable checks\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_ENABLE_CLANG_FORMAT \"Enable clang-format\" ${WEBVIEW_ENABLE_CHECKS})\n    option(WEBVIEW_ENABLE_CLANG_TIDY \"Enable clang-tidy\" ${WEBVIEW_ENABLE_CHECKS})\n    option(WEBVIEW_ENABLE_PACKAGING \"Enable packaging\" ${WEBVIEW_IS_TOP_LEVEL_BUILD})\n    option(WEBVIEW_STRICT_CHECKS \"Make checks strict\" ${WEBVIEW_IS_CI})\n    cmake_dependent_option(WEBVIEW_PACKAGE_AMALGAMATION \"Package amalgamated library\" ON WEBVIEW_ENABLE_PACKAGING OFF)\n    cmake_dependent_option(WEBVIEW_PACKAGE_DOCS \"Package documentation\" ON WEBVIEW_ENABLE_PACKAGING OFF)\n    cmake_dependent_option(WEBVIEW_PACKAGE_HEADERS \"Package headers\" ON WEBVIEW_ENABLE_PACKAGING OFF)\n    cmake_dependent_option(WEBVIEW_PACKAGE_LIB \"Package compiled libraries\" ON WEBVIEW_ENABLE_PACKAGING OFF)\n    option(WEBVIEW_STRICT_CLANG_FORMAT \"Make clang-format check strict\" ${WEBVIEW_STRICT_CHECKS})\n    option(WEBVIEW_STRICT_CLANG_TIDY \"Make clang-tidy check strict\" ${WEBVIEW_STRICT_CHECKS})\nendmacro()\n\nmacro(webview_set_install_rpath)\n    if(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\" OR CMAKE_SYSTEM_NAME STREQUAL \"Linux\")\n        # RPATH/RUNPATH\n        if(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n            set(RPATH_BASE @loader_path)\n        else()\n            set(RPATH_BASE $ORIGIN)\n        endif()\n\n        file(RELATIVE_PATH RPATH_SUBDIR\n            \"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}\")\n        set(CMAKE_INSTALL_RPATH \"${RPATH_BASE}\" \"${RPATH_BASE}/${RPATH_SUBDIR}\")\n    endif()\nendmacro()\n"
  },
  {
    "path": "cmake/modules/FindMSWebView2.cmake",
    "content": "if(DEFINED MSWebView2_ROOT)\n    find_path(MSWebView2_INCLUDE_DIR WebView2.h\n        PATHS\n            \"${MSWebView2_ROOT}/build/native\"\n            \"${MSWebView2_ROOT}\"\n        PATH_SUFFIXES include\n        NO_CMAKE_FIND_ROOT_PATH)\nendif()\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(MSWebView2 REQUIRED_VARS MSWebView2_INCLUDE_DIR)\n\nif(MSWebView2_FOUND)\n    if(NOT TARGET MSWebView2::headers)\n        add_library(MSWebView2::headers INTERFACE IMPORTED)\n        set_target_properties(MSWebView2::headers PROPERTIES\n            INTERFACE_INCLUDE_DIRECTORIES \"${MSWebView2_INCLUDE_DIR}\")\n        target_compile_features(MSWebView2::headers INTERFACE cxx_std_11)\n    endif()\nendif()\n"
  },
  {
    "path": "cmake/toolchains/arm64-windows-msvc.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR ARM64)\n\nset(CMAKE_C_COMPILER cl)\nset(CMAKE_CXX_COMPILER cl)\n\nset(CMAKE_GENERATOR_PLATFORM ARM64 CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/toolchains/host-gnu.cmake",
    "content": "set(CMAKE_C_COMPILER \"gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n"
  },
  {
    "path": "cmake/toolchains/host-llvm.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n"
  },
  {
    "path": "cmake/toolchains/i686-w64-mingw32.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR i686)\n\nset(CMAKE_SYSROOT /usr/i686-w64-mingw32)\nset(CMAKE_C_COMPILER \"i686-w64-mingw32-gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"i686-w64-mingw32-g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_RANLIB i686-w64-mingw32-ranlib)\nset(CMAKE_RC_COMPILER i686-w64-mingw32-windres)\n\nset(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\nset(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)\nset(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)\n"
  },
  {
    "path": "cmake/toolchains/i686-windows-msvc.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR x86)\n\nset(CMAKE_C_COMPILER cl)\nset(CMAKE_CXX_COMPILER cl)\n\nset(CMAKE_GENERATOR_PLATFORM Win32 CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/toolchains/universal-macos-llvm.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Darwin)\n\nset(CMAKE_C_COMPILER \"clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n\nset(CMAKE_OSX_ARCHITECTURES \"arm64;x86_64\" CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/toolchains/x86_64-msys2-gnu-ucrt64.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR x86_64)\n\nset(CMAKE_C_COMPILER \"gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n\nset(MSYSTEM ucrt64 CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/toolchains/x86_64-msys2-llvm-clang64.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR x86_64)\n\nset(CMAKE_C_COMPILER \"clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\n\nset(MSYSTEM clang64 CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/toolchains/x86_64-w64-mingw32.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR x86_64)\n\nset(CMAKE_SYSROOT /usr/x86_64-w64-mingw32)\nset(CMAKE_C_COMPILER \"x86_64-w64-mingw32-gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_CXX_COMPILER \"x86_64-w64-mingw32-g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}\")\nset(CMAKE_RANLIB x86_64-w64-mingw32-ranlib)\nset(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)\n\nset(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\nset(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)\nset(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)\n"
  },
  {
    "path": "cmake/toolchains/x86_64-windows-msvc.cmake",
    "content": "set(CMAKE_SYSTEM_NAME Windows)\nset(CMAKE_SYSTEM_PROCESSOR AMD64)\n\nset(CMAKE_C_COMPILER cl)\nset(CMAKE_CXX_COMPILER cl)\n\nset(CMAKE_GENERATOR_PLATFORM x64 CACHE INTERNAL \"\")\n"
  },
  {
    "path": "cmake/webview-config.cmake.in",
    "content": "@PACKAGE_INIT@\n\ninclude(CMakeFindDependencyMacro)\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/webview.cmake\")\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}/modules\")\n\nwebview_options()\nwebview_find_dependencies()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/webview-targets.cmake\")\n"
  },
  {
    "path": "cmake/webview.cmake",
    "content": "macro(webview_options)\n    if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n        set(WEBVIEW_MSWEBVIEW2_VERSION \"1.0.1150.38\" CACHE STRING \"MS WebView2 version\")\n        option(WEBVIEW_USE_BUILTIN_MSWEBVIEW2 \"Use built-in MS WebView2\" ON)\n    endif()\nendmacro()\n\nmacro(webview_find_dependencies)\n    if(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n        list(APPEND WEBVIEW_DEPENDENCIES \"-framework WebKit\" dl)\n    elseif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n        if(WEBVIEW_USE_BUILTIN_MSWEBVIEW2)\n            find_package(MSWebView2 QUIET)\n            if(NOT MSWebView2_FOUND)\n                webview_fetch_mswebview2(${WEBVIEW_MSWEBVIEW2_VERSION})\n            endif()\n            find_package(MSWebView2 REQUIRED)\n            if(MSWebView2_FOUND)\n                list(APPEND WEBVIEW_DEPENDENCIES MSWebView2::headers)\n            endif()\n        endif()\n        list(APPEND WEBVIEW_DEPENDENCIES advapi32 ole32 shell32 shlwapi user32 version)\n    else()\n        find_package(PkgConfig REQUIRED)\n\n        # List of preferred WebkitGTK modules (from most to least preferred)\n        set(WEBVIEW_WEBKITGTK_PREFERRED_API_LIST webkit2gtk-4.1)\n        # List of known WebkitGTK modules (from higher to lower version)\n        set(WEBVIEW_WEBKITGTK_KNOWN_API_LIST webkitgtk-6.0 webkit2gtk-4.1 webkit2gtk-4.0)\n\n        # Try to find specific WebKitGTK API\n        if(NOT \"${WEBVIEW_WEBKITGTK_API}\" STREQUAL \"\")\n            if(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 6.0)\n                pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkitgtk-6.0)\n            elseif(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 4.1)\n                pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkit2gtk-4.1)\n            elseif(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 4.0)\n                pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkit2gtk-4.0)\n            else()\n                message(FATAL_ERROR \"Unsupported WebKitGTK API: ${WEBVIEW_WEBKITGTK_API}\")\n            endif()\n        endif()\n\n        if(\"${WEBVIEW_WEBKITGTK_MODULE_NAME}\" STREQUAL \"\")\n            # Try to find a preferred WebKitGTK API\n            pkg_search_module(WEBVIEW_WEBKITGTK IMPORTED_TARGET ${WEBVIEW_WEBKITGTK_PREFERRED_API_LIST})\n            if (NOT WEBVIEW_WEBKITGTK_FOUND)\n              message(STATUS \"Trying to find any WebKitGTK API\")\n              pkg_search_module(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET ${WEBVIEW_WEBKITGTK_KNOWN_API_LIST})\n            endif()\n        else()\n            pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET \"${WEBVIEW_WEBKITGTK_MODULE_NAME}\")\n        endif()\n\n        if(\"${WEBVIEW_WEBKITGTK_MODULE_NAME}\" STREQUAL \"webkitgtk-6.0\")\n            set(WEBVIEW_WEBKITGTK_API 6.0)\n        elseif(\"${WEBVIEW_WEBKITGTK_MODULE_NAME}\" STREQUAL \"webkit2gtk-4.1\")\n            set(WEBVIEW_WEBKITGTK_API 4.1)\n        elseif(\"${WEBVIEW_WEBKITGTK_MODULE_NAME}\" STREQUAL \"webkit2gtk-4.0\")\n            set(WEBVIEW_WEBKITGTK_API 4.0)\n        else()\n            message(FATAL_ERROR \"Couldn't find any supported WebKitGTK API\")\n        endif()\n\n        # Find matching GTK module\n        if(\"${WEBVIEW_WEBKITGTK_API}\" VERSION_GREATER_EQUAL 6.0)\n            pkg_check_modules(WEBVIEW_GTK REQUIRED IMPORTED_TARGET gtk4)\n        elseif(\"${WEBVIEW_WEBKITGTK_API}\" VERSION_LESS 5.0)\n            pkg_check_modules(WEBVIEW_GTK REQUIRED IMPORTED_TARGET gtk+-3.0)\n        endif()\n\n        list(APPEND WEBVIEW_DEPENDENCIES PkgConfig::WEBVIEW_WEBKITGTK PkgConfig::WEBVIEW_GTK dl)\n    endif()\nendmacro()\n\nfunction(webview_fetch_mswebview2 VERSION)\n    cmake_policy(PUSH)\n    # Avoid warning related to FetchContent and DOWNLOAD_EXTRACT_TIMESTAMP\n    if(POLICY CMP0135)\n        cmake_policy(SET CMP0135 NEW)\n    endif()\n    if(NOT COMMAND FetchContent_Declare)\n        include(FetchContent)\n    endif()\n    set(FC_NAME microsoft_web_webview2)\n    FetchContent_Declare(${FC_NAME}\n        URL \"https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2/${VERSION}\")\n    FetchContent_MakeAvailable(${FC_NAME})\n    set(MSWebView2_ROOT \"${${FC_NAME}_SOURCE_DIR}\")\n    set(MSWebView2_ROOT \"${MSWebView2_ROOT}\" PARENT_SCOPE)\n    cmake_policy(POP)\nendfunction()\n"
  },
  {
    "path": "compatibility/CMakeLists.txt",
    "content": "if(WEBVIEW_USE_COMPAT_MINGW)\n    add_subdirectory(mingw)\nendif()\n"
  },
  {
    "path": "compatibility/mingw/CMakeLists.txt",
    "content": "# Compatibility target for MinGW that can be used to work around missing\n# \"EventToken.h\" header (used by MS WebView2) when targetting Windows.\n\nif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n    add_library(webview_compat_mingw INTERFACE)\n    add_library(webview::compat_mingw ALIAS webview_compat_mingw)\n    set_target_properties(webview_compat_mingw PROPERTIES\n        EXPORT_NAME compat_mingw)\n    target_include_directories(\n        webview_compat_mingw\n        INTERFACE\n            \"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\"\n            \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\nendif()\n"
  },
  {
    "path": "compatibility/mingw/include/EventToken.h",
    "content": "#ifndef WEBVIEW_COMPAT_EVENTTOKEN_H\n#define WEBVIEW_COMPAT_EVENTTOKEN_H\n#ifdef _WIN32\n\n// This compatibility header provides types used by MS WebView2. This header can\n// be used as an alternative to the \"EventToken.h\" header normally provided by\n// the Windows SDK. Depending on the MinGW distribution, this header may not be\n// present, or it may be present with the name \"eventtoken.h\". The letter casing\n// matters when cross-compiling on a system with case-sensitive file names.\n\n#ifndef __eventtoken_h__\n\n#ifdef __cplusplus\n#include <cstdint>\n#else\n#include <stdint.h>\n#endif\n\ntypedef struct EventRegistrationToken {\n  int64_t value;\n} EventRegistrationToken;\n#endif // __eventtoken_h__\n\n#endif // _WIN32\n#endif // WEBVIEW_COMPAT_EVENTTOKEN_H\n"
  },
  {
    "path": "core/CMakeLists.txt",
    "content": "# Core header library\nadd_library(webview_core_headers INTERFACE)\nadd_library(webview::core ALIAS webview_core_headers)\ntarget_include_directories(\n    webview_core_headers\n    INTERFACE\n        \"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\"\n        \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\ntarget_link_libraries(webview_core_headers INTERFACE ${WEBVIEW_DEPENDENCIES})\n# Note that we also use CMAKE_CXX_STANDARD which can override this\ntarget_compile_features(webview_core_headers INTERFACE cxx_std_11)\nset_target_properties(webview_core_headers PROPERTIES\n    EXPORT_NAME core)\n\nif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\" AND WEBVIEW_USE_COMPAT_MINGW)\n    target_link_libraries(webview_core_headers INTERFACE webview::compat_mingw)\nendif()\n\n# Core shared library\nif(WEBVIEW_BUILD_SHARED_LIBRARY)\n    add_library(webview_core_shared SHARED)\n    add_library(webview::core_shared ALIAS webview_core_shared)\n    target_sources(webview_core_shared PRIVATE src/webview.cc)\n    target_link_libraries(webview_core_shared PUBLIC webview_core_headers)\n    set_target_properties(webview_core_shared PROPERTIES\n        OUTPUT_NAME webview\n        VERSION \"${WEBVIEW_VERSION_NUMBER}\"\n        SOVERSION \"${WEBVIEW_VERSION_COMPATIBILITY}\"\n        EXPORT_NAME core_shared)\n    target_compile_definitions(webview_core_shared\n        INTERFACE WEBVIEW_SHARED\n        PRIVATE WEBVIEW_BUILD_SHARED)\nendif()\n\n# Core static library\nif(WEBVIEW_BUILD_STATIC_LIBRARY)\n    # Change .lib file name for MSVC because otherwise it would be the same for shared and static\n    if(MSVC)\n        set(STATIC_LIBRARY_OUTPUT_NAME webview_static)\n    else()\n        set(STATIC_LIBRARY_OUTPUT_NAME webview)\n    endif()\n\n    add_library(webview_core_static STATIC)\n    add_library(webview::core_static ALIAS webview_core_static)\n    target_sources(webview_core_static PRIVATE src/webview.cc)\n    target_link_libraries(webview_core_static PUBLIC webview_core_headers)\n    set_target_properties(webview_core_static PROPERTIES\n        OUTPUT_NAME \"${STATIC_LIBRARY_OUTPUT_NAME}\"\n        POSITION_INDEPENDENT_CODE ON\n        EXPORT_NAME core_static)\n    target_compile_definitions(webview_core_static PUBLIC WEBVIEW_STATIC)\nendif()\n\nif(WEBVIEW_BUILD_TESTS)\n    add_subdirectory(tests)\nendif()\n\nif(WEBVIEW_BUILD_AMALGAMATION)\n    webview_find_python3(${WEBVIEW_IS_CI})\n    if(Python3_FOUND)\n        webview_find_clang_format(${WEBVIEW_IS_CI})\n        if(WEBVIEW_CLANG_FORMAT_EXE)\n            file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS include/**)\n            file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS src/**)\n            set(AMALGAMATION_STAMP_FILE \"${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h.stamp\")\n\n            add_custom_command(\n                OUTPUT \"${AMALGAMATION_STAMP_FILE}\"\n                COMMAND \"${CMAKE_COMMAND}\" -E touch \"${AMALGAMATION_STAMP_FILE}\"\n                COMMAND ${Python3_EXECUTABLE}\n                    \"${PROJECT_SOURCE_DIR}/scripts/amalgamate/amalgamate.py\"\n                    --clang-format-exe \"${WEBVIEW_CLANG_FORMAT_EXE}\"\n                    --base \"${CMAKE_CURRENT_SOURCE_DIR}\"\n                    --search include\n                    --output \"${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h\"\n                    ${SOURCE_FILES}\n                DEPENDS ${HEADER_FILES} ${SOURCE_FILES}\n                COMMENT \"Building amalgamation...\"\n                VERBATIM)\n\n            add_custom_target(webview_amalgamate ALL\n                DEPENDS \"${AMALGAMATION_STAMP_FILE}\")\n\n            install(FILES \"${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h\"\n                DESTINATION .\n                COMPONENT webview_amalgamation)\n        else()\n            message(WARNING \"Skipping amalgamation as clang-format was not found\")\n        endif()\n    else()\n        message(WARNING \"Skipping amalgamation as Python 3 was not found\")\n    endif()\nendif()\n"
  },
  {
    "path": "core/include/webview/api.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_API_H\n#define WEBVIEW_API_H\n\n#include \"errors.h\"\n#include \"macros.h\"\n#include \"types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Creates a new webview instance.\n *\n * @param debug Enable developer tools if supported by the backend.\n * @param window Optional native window handle, i.e. @c GtkWindow pointer\n *        @c NSWindow pointer (Cocoa) or @c HWND (Win32). If non-null,\n *        the webview widget is embedded into the given window, and the\n *        caller is expected to assume responsibility for the window as\n *        well as application lifecycle. If the window handle is null,\n *        a new window is created and both the window and application\n *        lifecycle are managed by the webview instance.\n * @remark Win32: The function also accepts a pointer to @c HWND (Win32) in the\n *         window parameter for backward compatibility.\n * @remark Win32/WebView2: @c CoInitializeEx should be called with\n *         @c COINIT_APARTMENTTHREADED before attempting to call this function\n *         with an existing window. Omitting this step may cause WebView2\n *         initialization to fail.\n * @return @c NULL on failure. Creation can fail for various reasons such\n *         as when required runtime dependencies are missing or when window\n *         creation fails.\n * @retval WEBVIEW_ERROR_MISSING_DEPENDENCY\n *         May be returned if WebView2 is unavailable on Windows.\n */\nWEBVIEW_API webview_t webview_create(int debug, void *window);\n\n/**\n * Destroys a webview instance and closes the native window.\n *\n * @param w The webview instance.\n */\nWEBVIEW_API webview_error_t webview_destroy(webview_t w);\n\n/**\n * Runs the main loop until it's terminated.\n *\n * @param w The webview instance.\n */\nWEBVIEW_API webview_error_t webview_run(webview_t w);\n\n/**\n * Stops the main loop. It is safe to call this function from another\n * background thread.\n *\n * @param w The webview instance.\n */\nWEBVIEW_API webview_error_t webview_terminate(webview_t w);\n\n/**\n * Schedules a function to be invoked on the thread with the run/event loop.\n *\n * Since library functions generally do not have thread safety guarantees,\n * this function can be used to schedule code to execute on the main/GUI\n * thread and thereby make that execution safe in multi-threaded applications.\n *\n * @param w The webview instance.\n * @param fn The function to be invoked.\n * @param arg An optional argument passed along to the callback function.\n */\nWEBVIEW_API webview_error_t webview_dispatch(webview_t w,\n                                             void (*fn)(webview_t w, void *arg),\n                                             void *arg);\n\n/**\n * Returns the native handle of the window associated with the webview instance.\n * The handle can be a @c GtkWindow pointer (GTK), @c NSWindow pointer (Cocoa)\n * or @c HWND (Win32).\n *\n * @param w The webview instance.\n * @return The handle of the native window.\n */\nWEBVIEW_API void *webview_get_window(webview_t w);\n\n/**\n * Get a native handle of choice.\n *\n * @param w The webview instance.\n * @param kind The kind of handle to retrieve.\n * @return The native handle or @c NULL.\n * @since 0.11\n */\nWEBVIEW_API void *webview_get_native_handle(webview_t w,\n                                            webview_native_handle_kind_t kind);\n\n/**\n * Updates the title of the native window.\n *\n * @param w The webview instance.\n * @param title The new title.\n */\nWEBVIEW_API webview_error_t webview_set_title(webview_t w, const char *title);\n\n/**\n * Updates the size of the native window.\n *\n * Remarks:\n * - Subsequent calls to this function may behave inconsistently across\n *   different versions of GTK and windowing systems (X11/Wayland).\n * - Using WEBVIEW_HINT_MAX for setting the maximum window size is not\n *   supported with GTK 4 because X11-specific functions such as\n *   gtk_window_set_geometry_hints were removed. This option has no effect\n *   when using GTK 4.\n *\n * @param w The webview instance.\n * @param width New width.\n * @param height New height.\n * @param hints Size hints.\n */\nWEBVIEW_API webview_error_t webview_set_size(webview_t w, int width, int height,\n                                             webview_hint_t hints);\n\n/**\n * Navigates webview to the given URL. URL may be a properly encoded data URI.\n *\n * Example:\n * @code{.c}\n * webview_navigate(w, \"https://github.com/webview/webview\");\n * webview_navigate(w, \"data:text/html,%3Ch1%3EHello%3C%2Fh1%3E\");\n * webview_navigate(w, \"data:text/html;base64,PGgxPkhlbGxvPC9oMT4=\");\n * @endcode\n *\n * @param w The webview instance.\n * @param url URL.\n */\nWEBVIEW_API webview_error_t webview_navigate(webview_t w, const char *url);\n\n/**\n * Load HTML content into the webview.\n *\n * Example:\n * @code{.c}\n * webview_set_html(w, \"<h1>Hello</h1>\");\n * @endcode\n *\n * @param w The webview instance.\n * @param html HTML content.\n */\nWEBVIEW_API webview_error_t webview_set_html(webview_t w, const char *html);\n\n/**\n * Injects JavaScript code to be executed immediately upon loading a page.\n * The code will be executed before @c window.onload.\n *\n * @param w The webview instance.\n * @param js JS content.\n */\nWEBVIEW_API webview_error_t webview_init(webview_t w, const char *js);\n\n/**\n * Evaluates arbitrary JavaScript code.\n *\n * Use bindings if you need to communicate the result of the evaluation.\n *\n * @param w The webview instance.\n * @param js JS content.\n */\nWEBVIEW_API webview_error_t webview_eval(webview_t w, const char *js);\n\n/**\n * Binds a function pointer to a new global JavaScript function.\n *\n * Internally, JS glue code is injected to create the JS function by the\n * given name. The callback function is passed a request identifier,\n * a request string and a user-provided argument. The request string is\n * a JSON array of the arguments passed to the JS function.\n *\n * @param w The webview instance.\n * @param name Name of the JS function.\n * @param fn Callback function.\n * @param arg User argument.\n * @retval WEBVIEW_ERROR_DUPLICATE\n *         A binding already exists with the specified name.\n */\nWEBVIEW_API webview_error_t webview_bind(webview_t w, const char *name,\n                                         void (*fn)(const char *id,\n                                                    const char *req, void *arg),\n                                         void *arg);\n\n/**\n * Removes a binding created with webview_bind().\n *\n * @param w The webview instance.\n * @param name Name of the binding.\n * @retval WEBVIEW_ERROR_NOT_FOUND No binding exists with the specified name.\n */\nWEBVIEW_API webview_error_t webview_unbind(webview_t w, const char *name);\n\n/**\n * Responds to a binding call from the JS side.\n *\n * This function is safe to call from another thread.\n *\n * @param w The webview instance.\n * @param id The identifier of the binding call. Pass along the value received\n *           in the binding handler (see webview_bind()).\n * @param status A status of zero tells the JS side that the binding call was\n *               successful; any other value indicates an error.\n * @param result The result of the binding call to be returned to the JS side.\n *               This must either be a valid JSON value or an empty string for\n *               the primitive JS value @c undefined.\n */\nWEBVIEW_API webview_error_t webview_return(webview_t w, const char *id,\n                                           int status, const char *result);\n\n/**\n * Get the library's version information.\n *\n * @since 0.10\n */\nWEBVIEW_API const webview_version_info_t *webview_version(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // WEBVIEW_API_H\n"
  },
  {
    "path": "core/include/webview/backends.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_HH\n#define WEBVIEW_BACKENDS_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"detail/backends/cocoa_webkit.hh\"\n#include \"detail/backends/gtk_webkitgtk.hh\"\n#include \"detail/backends/win32_edge.hh\"\n\nnamespace webview {\nusing webview = browser_engine;\n}\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_HH\n"
  },
  {
    "path": "core/include/webview/c_api_impl.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_C_API_IMPL_HH\n#define WEBVIEW_C_API_IMPL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"backends.hh\"\n#include \"errors.h\"\n#include \"errors.hh\"\n#include \"json_deprecated.hh\"\n#include \"macros.h\"\n#include \"types.h\"\n#include \"version.h\"\n\nnamespace webview {\nnamespace detail {\n\n// The library's version information.\nconstexpr const webview_version_info_t library_version_info{\n    {WEBVIEW_VERSION_MAJOR, WEBVIEW_VERSION_MINOR, WEBVIEW_VERSION_PATCH},\n    WEBVIEW_VERSION_NUMBER,\n    WEBVIEW_VERSION_PRE_RELEASE,\n    WEBVIEW_VERSION_BUILD_METADATA};\n\ntemplate <typename WorkFn, typename ResultFn>\nwebview_error_t api_filter(WorkFn &&do_work, ResultFn &&put_result) noexcept {\n  try {\n    auto result = do_work();\n    if (result.ok()) {\n      put_result(result.value());\n      return WEBVIEW_ERROR_OK;\n    }\n    return result.error().code();\n  } catch (const exception &e) {\n    return e.error().code();\n  } catch (...) {\n    return WEBVIEW_ERROR_UNSPECIFIED;\n  }\n}\n\ntemplate <typename WorkFn>\nwebview_error_t api_filter(WorkFn &&do_work) noexcept {\n  try {\n    auto result = do_work();\n    if (result.ok()) {\n      return WEBVIEW_ERROR_OK;\n    }\n    return result.error().code();\n  } catch (const exception &e) {\n    return e.error().code();\n  } catch (...) {\n    return WEBVIEW_ERROR_UNSPECIFIED;\n  }\n}\n\ninline webview *cast_to_webview(void *w) {\n  if (!w) {\n    throw exception{WEBVIEW_ERROR_INVALID_ARGUMENT,\n                    \"Cannot cast null pointer to webview instance\"};\n  }\n  return static_cast<webview *>(w);\n}\n\n} // namespace detail\n} // namespace webview\n\nWEBVIEW_API webview_t webview_create(int debug, void *wnd) {\n  using namespace webview::detail;\n  webview::webview *w{};\n  auto err = api_filter(\n      [=]() -> webview::result<webview::webview *> {\n        return new webview::webview{static_cast<bool>(debug), wnd};\n      },\n      [&](webview::webview *w_) { w = w_; });\n  if (err == WEBVIEW_ERROR_OK) {\n    return w;\n  }\n  return nullptr;\n}\n\nWEBVIEW_API webview_error_t webview_destroy(webview_t w) {\n  using namespace webview::detail;\n  return api_filter([=]() -> webview::noresult {\n    delete cast_to_webview(w);\n    return {};\n  });\n}\n\nWEBVIEW_API webview_error_t webview_run(webview_t w) {\n  using namespace webview::detail;\n  return api_filter([=] { return cast_to_webview(w)->run(); });\n}\n\nWEBVIEW_API webview_error_t webview_terminate(webview_t w) {\n  using namespace webview::detail;\n  return api_filter([=] { return cast_to_webview(w)->terminate(); });\n}\n\nWEBVIEW_API webview_error_t webview_dispatch(webview_t w,\n                                             void (*fn)(webview_t, void *),\n                                             void *arg) {\n  using namespace webview::detail;\n  if (!fn) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter(\n      [=] { return cast_to_webview(w)->dispatch([=]() { fn(w, arg); }); });\n}\n\nWEBVIEW_API void *webview_get_window(webview_t w) {\n  using namespace webview::detail;\n  void *window = nullptr;\n  auto err = api_filter([=] { return cast_to_webview(w)->window(); },\n                        [&](void *value) { window = value; });\n  if (err == WEBVIEW_ERROR_OK) {\n    return window;\n  }\n  return nullptr;\n}\n\nWEBVIEW_API void *webview_get_native_handle(webview_t w,\n                                            webview_native_handle_kind_t kind) {\n  using namespace webview::detail;\n  void *handle{};\n  auto err = api_filter(\n      [=]() -> webview::result<void *> {\n        auto *w_ = cast_to_webview(w);\n        switch (kind) {\n        case WEBVIEW_NATIVE_HANDLE_KIND_UI_WINDOW:\n          return w_->window();\n        case WEBVIEW_NATIVE_HANDLE_KIND_UI_WIDGET:\n          return w_->widget();\n        case WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER:\n          return w_->browser_controller();\n        default:\n          return webview::error_info{WEBVIEW_ERROR_INVALID_ARGUMENT};\n        }\n      },\n      [&](void *handle_) { handle = handle_; });\n  if (err == WEBVIEW_ERROR_OK) {\n    return handle;\n  }\n  return nullptr;\n}\n\nWEBVIEW_API webview_error_t webview_set_title(webview_t w, const char *title) {\n  using namespace webview::detail;\n  if (!title) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->set_title(title); });\n}\n\nWEBVIEW_API webview_error_t webview_set_size(webview_t w, int width, int height,\n                                             webview_hint_t hints) {\n  using namespace webview::detail;\n  return api_filter(\n      [=] { return cast_to_webview(w)->set_size(width, height, hints); });\n}\n\nWEBVIEW_API webview_error_t webview_navigate(webview_t w, const char *url) {\n  using namespace webview::detail;\n  if (!url) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->navigate(url); });\n}\n\nWEBVIEW_API webview_error_t webview_set_html(webview_t w, const char *html) {\n  using namespace webview::detail;\n  if (!html) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->set_html(html); });\n}\n\nWEBVIEW_API webview_error_t webview_init(webview_t w, const char *js) {\n  using namespace webview::detail;\n  if (!js) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->init(js); });\n}\n\nWEBVIEW_API webview_error_t webview_eval(webview_t w, const char *js) {\n  using namespace webview::detail;\n  if (!js) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->eval(js); });\n}\n\nWEBVIEW_API webview_error_t webview_bind(webview_t w, const char *name,\n                                         void (*fn)(const char *id,\n                                                    const char *req, void *arg),\n                                         void *arg) {\n  using namespace webview::detail;\n  if (!name || !fn) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] {\n    return cast_to_webview(w)->bind(\n        name,\n        [=](const std::string &seq, const std::string &req, void *arg_) {\n          fn(seq.c_str(), req.c_str(), arg_);\n        },\n        arg);\n  });\n}\n\nWEBVIEW_API webview_error_t webview_unbind(webview_t w, const char *name) {\n  using namespace webview::detail;\n  if (!name) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter([=] { return cast_to_webview(w)->unbind(name); });\n}\n\nWEBVIEW_API webview_error_t webview_return(webview_t w, const char *id,\n                                           int status, const char *result) {\n  using namespace webview::detail;\n  if (!id || !result) {\n    return WEBVIEW_ERROR_INVALID_ARGUMENT;\n  }\n  return api_filter(\n      [=] { return cast_to_webview(w)->resolve(id, status, result); });\n}\n\nWEBVIEW_API const webview_version_info_t *webview_version(void) {\n  return &webview::detail::library_version_info;\n}\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_C_API_IMPL_HH\n"
  },
  {
    "path": "core/include/webview/detail/backends/cocoa_webkit.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_COCOA_WEBKIT_HH\n#define WEBVIEW_BACKENDS_COCOA_WEBKIT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n//\n// ====================================================================\n//\n// This implementation uses Cocoa WKWebView backend on macOS. It is\n// written using ObjC runtime and uses WKWebView class as a browser runtime.\n// You should pass \"-framework Webkit\" flag to the compiler.\n//\n// ====================================================================\n//\n\n#include \"../../types.hh\"\n#include \"../engine_base.hh\"\n#include \"../platform/darwin/cocoa/cocoa.hh\"\n#include \"../platform/darwin/objc/objc.hh\"\n#include \"../platform/darwin/webkit/webkit.hh\"\n#include \"../user_script.hh\"\n\n#include <atomic>\n#include <functional>\n#include <list>\n#include <memory>\n#include <string>\n\n#include <objc/objc-runtime.h>\n\nnamespace webview {\nnamespace detail {\n\nclass user_script::impl {\npublic:\n  impl(id script) : m_script{objc::retain(script)} {}\n\n  ~impl() { objc::release(m_script); }\n\n  impl(const impl &) = delete;\n  impl &operator=(const impl &) = delete;\n  impl(impl &&) = delete;\n  impl &operator=(impl &&) = delete;\n\n  id get_native() const { return m_script; }\n\nprivate:\n  id m_script{};\n};\n\n// Encapsulate backend in its own namespace to avoid polluting the parent\n// namespace when pulling in commonly-used symbols from other namespaces.\n// Since those commmon symbols are used a lot, this reduces the overall\n// noise in the code.\nnamespace cocoa_webkit {\n\nusing namespace cocoa;\nusing namespace webkit;\n\nclass cocoa_wkwebview_engine : public engine_base {\npublic:\n  cocoa_wkwebview_engine(bool debug, void *window)\n      : engine_base{!window}, m_app{NSApplication_get_sharedApplication()} {\n    window_init(window);\n    window_settings(debug);\n    dispatch_size_default();\n  }\n\n  cocoa_wkwebview_engine(const cocoa_wkwebview_engine &) = delete;\n  cocoa_wkwebview_engine &operator=(const cocoa_wkwebview_engine &) = delete;\n  cocoa_wkwebview_engine(cocoa_wkwebview_engine &&) = delete;\n  cocoa_wkwebview_engine &operator=(cocoa_wkwebview_engine &&) = delete;\n\n  virtual ~cocoa_wkwebview_engine() {\n    objc::autoreleasepool arp;\n    if (m_window) {\n      if (m_webview) {\n        if (auto ui_delegate{WKWebView_get_UIDelegate(m_webview)}) {\n          WKWebView_set_UIDelegate(m_webview, nullptr);\n          objc::release(ui_delegate);\n        }\n        objc::release(m_webview);\n        m_webview = nullptr;\n      }\n      if (m_widget) {\n        if (m_widget == NSWindow_get_contentView(m_window)) {\n          NSWindow_set_contentView(m_window, nullptr);\n        }\n        objc::release(m_widget);\n        m_widget = nullptr;\n      }\n      if (owns_window()) {\n        // Replace delegate to avoid callbacks and other bad things during\n        // destruction.\n        NSWindow_set_delegate(m_window, nullptr);\n        NSWindow_close(m_window);\n        on_window_destroyed(true);\n      }\n      m_window = nullptr;\n    }\n    if (m_window_delegate) {\n      objc::release(m_window_delegate);\n      m_window_delegate = nullptr;\n    }\n    if (m_app_delegate) {\n      NSApplication_set_delegate(m_app, nullptr);\n      // Make sure to release the delegate we created.\n      objc::release(m_app_delegate);\n      m_app_delegate = nullptr;\n    }\n    if (owns_window()) {\n      // Needed for the window to close immediately.\n      deplete_run_loop_event_queue();\n    }\n    // TODO: Figure out why m_manager is still alive after the autoreleasepool\n    // has been drained.\n  }\n\nprotected:\n  result<void *> window_impl() override {\n    if (m_window) {\n      return m_window;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  result<void *> widget_impl() override {\n    if (m_widget) {\n      return m_widget;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  result<void *> browser_controller_impl() override {\n    if (m_webview) {\n      return m_webview;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  noresult terminate_impl() override {\n    stop_run_loop();\n    return {};\n  }\n\n  noresult run_impl() override {\n    NSApplication_run(m_app);\n    return {};\n  }\n\n  noresult dispatch_impl(std::function<void()> f) override {\n    dispatch_async_f(dispatch_get_main_queue(), new dispatch_fn_t(f),\n                     (dispatch_function_t)([](void *arg) {\n                       auto f = static_cast<dispatch_fn_t *>(arg);\n                       (*f)();\n                       delete f;\n                     }));\n    return {};\n  }\n\n  noresult set_title_impl(const std::string &title) override {\n    NSWindow_set_title(m_window, title);\n    return {};\n  }\n  noresult set_size_impl(int width, int height, webview_hint_t hints) override {\n    objc::autoreleasepool arp;\n\n    auto style = static_cast<NSWindowStyleMask>(\n        NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |\n        NSWindowStyleMaskMiniaturizable);\n    if (hints != WEBVIEW_HINT_FIXED) {\n      style =\n          static_cast<NSWindowStyleMask>(style | NSWindowStyleMaskResizable);\n    }\n    NSWindow_set_styleMask(m_window, style);\n\n    if (hints == WEBVIEW_HINT_MIN) {\n      NSWindow_set_contentMinSize(m_window, NSSizeMake(width, height));\n    } else if (hints == WEBVIEW_HINT_MAX) {\n      NSWindow_set_contentMaxSize(m_window, NSSizeMake(width, height));\n    } else {\n      auto rect{NSWindow_get_frame(m_window)};\n      NSWindow_setFrame(m_window,\n                        NSRectMake(rect.origin.x, rect.origin.y, width, height),\n                        true, false);\n    }\n    NSWindow_center(m_window);\n\n    return window_show();\n  }\n  noresult navigate_impl(const std::string &url) override {\n    objc::autoreleasepool arp;\n\n    WKWebView_loadRequest(\n        m_webview, NSURLRequest_requestWithURL(NSURL_URLWithString(url)));\n\n    return {};\n  }\n  noresult set_html_impl(const std::string &html) override {\n    objc::autoreleasepool arp;\n    WKWebView_loadHTMLString(m_webview, NSString_stringWithUTF8String(html),\n                             nullptr);\n    return {};\n  }\n  noresult eval_impl(const std::string &js) override {\n    objc::autoreleasepool arp;\n    // URI is null before content has begun loading.\n    auto nsurl{WKWebView_get_URL(m_webview)};\n    if (!nsurl) {\n      return {};\n    }\n    WKWebView_evaluateJavaScript(m_webview, NSString_stringWithUTF8String(js),\n                                 nullptr);\n    return {};\n  }\n\n  user_script add_user_script_impl(const std::string &js) override {\n    objc::autoreleasepool arp;\n    auto wk_script{WKUserScript_withSource(\n        NSString_stringWithUTF8String(js),\n        WKUserScriptInjectionTimeAtDocumentStart, true)};\n    // Script is retained when added.\n    WKUserContentController_addUserScript(m_manager, wk_script);\n    user_script script{\n        js, user_script::impl_ptr{new user_script::impl{wk_script},\n                                  [](user_script::impl *p) { delete p; }}};\n    return script;\n  }\n\n  void remove_all_user_scripts_impl(\n      const std::list<user_script> & /*scripts*/) override {\n    objc::autoreleasepool arp;\n    // Removing scripts decreases the retain count of each script.\n    WKUserContentController_removeAllUserScripts(m_manager);\n  }\n\n  bool are_user_scripts_equal_impl(const user_script &first,\n                                   const user_script &second) override {\n    auto *wk_first = first.get_impl().get_native();\n    auto *wk_second = second.get_impl().get_native();\n    return wk_first == wk_second;\n  }\n\nprivate:\n  id create_app_delegate() {\n    objc::autoreleasepool arp;\n    constexpr auto class_name = \"WebviewAppDelegate\";\n    // Avoid crash due to registering same class twice\n    auto cls = objc_lookUpClass(class_name);\n    if (!cls) {\n      // Note: Avoid registering the class name \"AppDelegate\" as it is the\n      // default name in projects created with Xcode, and using the same name\n      // causes objc_registerClassPair to crash.\n      cls =\n          objc_allocateClassPair(objc::get_class(\"NSResponder\"), class_name, 0);\n      class_addProtocol(cls, objc_getProtocol(\"NSTouchBarProvider\"));\n      class_addMethod(\n          cls,\n          objc::selector(\"applicationShouldTerminateAfterLastWindowClosed:\"),\n          (IMP)(+[](id, SEL, id) -> BOOL { return NO; }), \"c@:@\");\n      class_addMethod(cls, objc::selector(\"applicationDidFinishLaunching:\"),\n                      (IMP)(+[](id self, SEL, id notification) {\n                        auto app{NSNotification_get_object(notification)};\n                        auto w = get_associated_webview(self);\n                        w->on_application_did_finish_launching(self, app);\n                      }),\n                      \"v@:@\");\n      objc_registerClassPair(cls);\n    }\n    return objc::Class_new(cls);\n  }\n  id create_script_message_handler() {\n    objc::autoreleasepool arp;\n    constexpr auto class_name = \"WebviewWKScriptMessageHandler\";\n    // Avoid crash due to registering same class twice\n    auto cls = objc_lookUpClass(class_name);\n    if (!cls) {\n      cls =\n          objc_allocateClassPair(objc::get_class(\"NSResponder\"), class_name, 0);\n      class_addProtocol(cls, objc_getProtocol(\"WKScriptMessageHandler\"));\n      class_addMethod(\n          cls, objc::selector(\"userContentController:didReceiveScriptMessage:\"),\n          (IMP)(+[](id self, SEL, id, id msg) {\n            auto w = get_associated_webview(self);\n            w->on_message(\n                NSString_get_UTF8String(WKScriptMessage_get_body(msg)));\n          }),\n          \"v@:@@\");\n      objc_registerClassPair(cls);\n    }\n    auto instance{objc::Class_new(cls)};\n    set_associated_webview(instance, this);\n    return instance;\n  }\n  static id create_webkit_ui_delegate() {\n    objc::autoreleasepool arp;\n    constexpr auto class_name = \"WebviewWKUIDelegate\";\n    // Avoid crash due to registering same class twice\n    auto cls = objc_lookUpClass(class_name);\n    if (!cls) {\n      cls = objc_allocateClassPair(objc::get_class(\"NSObject\"), class_name, 0);\n      class_addProtocol(cls, objc_getProtocol(\"WKUIDelegate\"));\n      class_addMethod(\n          cls,\n          objc::selector(\"webView:runOpenPanelWithParameters:initiatedByFrame:\"\n                         \"completionHandler:\"),\n          (IMP)(+[](id, SEL, id, id parameters, id, id completion_handler) {\n            auto allows_multiple_selection{\n                WKOpenPanelParameters_get_allowsMultipleSelection(parameters)};\n            auto allows_directories{\n                WKOpenPanelParameters_get_allowsDirectories(parameters)};\n\n            // Show a panel for selecting files.\n            auto panel{NSOpenPanel_openPanel()};\n            NSOpenPanel_set_canChooseFiles(panel, true);\n            NSOpenPanel_set_canChooseDirectories(panel, allows_directories);\n            NSOpenPanel_set_allowsMultipleSelection(panel,\n                                                    allows_multiple_selection);\n            auto modal_response{NSSavePanel_runModal(panel)};\n\n            // Get the URLs for the selected files. If the modal was canceled\n            // then we pass null to the completion handler to signify\n            // cancellation.\n            id urls{modal_response == NSModalResponseOK\n                        ? NSOpenPanel_get_URLs(panel)\n                        : nullptr};\n\n            // Invoke the completion handler block.\n            auto sig{NSMethodSignature_signatureWithObjCTypes(\"v@?@\")};\n            auto invocation{NSInvocation_invocationWithMethodSignature(sig)};\n            NSInvocation_set_target(invocation, completion_handler);\n            NSInvocation_setArgument(invocation, &urls, 1);\n            NSInvocation_invoke(invocation);\n          }),\n          \"v@:@@@@\");\n      objc_registerClassPair(cls);\n    }\n    return objc::Class_new(cls);\n  }\n  static id create_window_delegate() {\n    objc::autoreleasepool arp;\n    constexpr auto class_name = \"WebviewNSWindowDelegate\";\n    // Avoid crash due to registering same class twice\n    auto cls = objc_lookUpClass(class_name);\n    if (!cls) {\n      cls = objc_allocateClassPair(objc::get_class(\"NSObject\"), class_name, 0);\n      class_addProtocol(cls, objc_getProtocol(\"NSWindowDelegate\"));\n      class_addMethod(cls, objc::selector(\"windowWillClose:\"),\n                      (IMP)(+[](id self, SEL, id notification) {\n                        auto window{NSNotification_get_object(notification)};\n                        auto w = get_associated_webview(self);\n                        w->on_window_will_close(self, window);\n                      }),\n                      \"v@:@\");\n      objc_registerClassPair(cls);\n    }\n    return objc::Class_new(cls);\n  }\n  static cocoa_wkwebview_engine *get_associated_webview(id object) {\n    objc::autoreleasepool arp;\n    if (id assoc_obj{objc_getAssociatedObject(object, \"webview\")}) {\n      cocoa_wkwebview_engine *w{};\n      NSValue_getValue(assoc_obj, &w, sizeof(w));\n      return w;\n    }\n    return nullptr;\n  }\n  static void set_associated_webview(id object, cocoa_wkwebview_engine *w) {\n    objc::autoreleasepool arp;\n    objc_setAssociatedObject(object, \"webview\", NSValue_valueWithPointer(w),\n                             OBJC_ASSOCIATION_RETAIN);\n  }\n  static bool is_app_bundled() noexcept {\n    auto bundle = NSBundle_get_mainBundle();\n    if (!bundle) {\n      return false;\n    }\n    auto bundle_path = NSBundle_get_bundlePath(bundle);\n    auto bundled =\n        NSString_hasSuffix(bundle_path, NSString_stringWithUTF8String(\".app\"));\n    return !!bundled;\n  }\n  void on_application_did_finish_launching(id /*delegate*/, id app) {\n    // See comments related to application lifecycle in create_app_delegate().\n    if (owns_window()) {\n      // Stop the main run loop so that we can return\n      // from the constructor.\n      stop_run_loop();\n    }\n\n    // Activate the app if it is not bundled.\n    // Bundled apps launched from Finder are activated automatically but\n    // otherwise not. Activating the app even when it has been launched from\n    // Finder does not seem to be harmful but calling this function is rarely\n    // needed as proper activation is normally taken care of for us.\n    // Bundled apps have a default activation policy of\n    // NSApplicationActivationPolicyRegular while non-bundled apps have a\n    // default activation policy of NSApplicationActivationPolicyProhibited.\n    if (!is_app_bundled()) {\n      // \"setActivationPolicy:\" must be invoked before\n      // \"activateIgnoringOtherApps:\" for activation to work.\n      NSApplication_setActivationPolicy(app,\n                                        NSApplicationActivationPolicyRegular);\n      // Activate the app regardless of other active apps.\n      // This can be obtrusive so we only do it when necessary.\n      NSApplication_activateIgnoringOtherApps(app, true);\n    }\n\n    window_init_proceed();\n  }\n  void on_window_will_close(id /*delegate*/, id /*window*/) {\n    // Widget destroyed along with window.\n    m_widget = nullptr;\n    m_webview = nullptr;\n    m_window = nullptr;\n    dispatch([this] { on_window_destroyed(); });\n  }\n  void window_settings(bool debug) {\n    objc::autoreleasepool arp;\n\n    auto config{objc::autorelease(WKWebViewConfiguration_new())};\n\n    m_manager = WKWebViewConfiguration_get_userContentController(config);\n\n    auto preferences = WKWebViewConfiguration_get_preferences(config);\n    auto yes_value = NSNumber_numberWithBool(true);\n\n    if (debug) {\n      NSObject_setValue_forKey(\n          preferences, yes_value,\n          NSString_stringWithUTF8String(\"developerExtrasEnabled\"));\n    }\n\n    NSObject_setValue_forKey(\n        preferences, yes_value,\n        NSString_stringWithUTF8String(\"fullScreenEnabled\"));\n\n#if defined(__has_builtin)\n#if __has_builtin(__builtin_available)\n    if (__builtin_available(macOS 10.13, *)) {\n      NSObject_setValue_forKey(\n          preferences, yes_value,\n          NSString_stringWithUTF8String(\"javaScriptCanAccessClipboard\"));\n      NSObject_setValue_forKey(\n          preferences, yes_value,\n          NSString_stringWithUTF8String(\"DOMPasteAllowed\"));\n    }\n#else\n#error __builtin_available not supported by compiler\n#endif\n#else\n#error __has_builtin not supported by compiler\n#endif\n\n    auto ui_delegate = create_webkit_ui_delegate();\n    m_webview =\n        objc::retain(WKWebView_withFrame(CGRectMake(0, 0, 0, 0), config));\n    // Autoresizing mask is needed to prevent the Web Inspector pane from\n    // pushing the main web view out of bounds\n    auto autoresizing_mask{static_cast<NSAutoresizingMaskOptions>(\n        NSViewWidthSizable | NSViewMaxXMargin | NSViewHeightSizable |\n        NSViewMaxYMargin)};\n    NSView_set_autoresizingMask(m_webview, autoresizing_mask);\n    set_associated_webview(ui_delegate, this);\n    WKWebView_set_UIDelegate(m_webview, ui_delegate);\n\n    if (debug) {\n      // Explicitly make WKWebView inspectable via Safari on OS versions that\n      // disable the feature by default (macOS 13.3 and later) and support\n      // enabling it. According to Apple, the behavior on older OS versions is\n      // for content to always be inspectable in \"debug builds\".\n      // Testing shows that this is true for macOS 12.6 but somehow not 10.15.\n      // https://webkit.org/blog/13936/enabling-the-inspection-of-web-content-in-apps/\n      WKWebView_set_inspectable(m_webview, true);\n    }\n\n    auto script_message_handler =\n        objc::autorelease(create_script_message_handler());\n    WKUserContentController_addScriptMessageHandler(\n        m_manager, script_message_handler,\n        NSString_stringWithUTF8String(\"__webview__\"));\n\n    add_init_script(\"function(message) {\\n\\\n  return window.webkit.messageHandlers.__webview__.postMessage(message);\\n\\\n}\");\n    set_up_widget();\n    NSWindow_set_contentView(m_window, m_widget);\n    if (owns_window()) {\n      NSWindow_makeKeyAndOrderFront(m_window);\n    }\n  }\n  void set_up_widget() {\n    objc::autoreleasepool arp;\n    // Create a new view that can contain both the web view and the Web Inspector pane\n    m_widget = objc::retain(NSView_withFrame(NSRectMake(0, 0, 0, 0)));\n    // Autoresizing is needed because the Web Inspector pane is a sibling of the web view\n    NSView_set_autoresizesSubviews(m_widget, true);\n    NSView_addSubview(m_widget, m_webview);\n    NSView_set_frame(m_webview, NSView_get_bounds(m_widget));\n  }\n  void stop_run_loop() {\n    objc::autoreleasepool arp;\n    // Request the run loop to stop. This doesn't immediately stop the loop.\n    NSApplication_stop(m_app);\n    // The run loop will stop after processing an NSEvent.\n    auto event{NSEvent_otherEventWithType(\n        NSEventTypeApplicationDefined, NSPointMake(0, 0),\n        NSEventModifierFlags{}, 0, 0, nullptr, 0, 0, 0)};\n    NSApplication_postEvent(m_app, event, true);\n  }\n  static bool get_and_set_is_first_instance() noexcept {\n    static std::atomic_bool first{true};\n    bool temp = first;\n    if (temp) {\n      first = false;\n    }\n    return temp;\n  }\n  void window_init(void *window) {\n    objc::autoreleasepool arp;\n\n    m_window = static_cast<id>(window);\n    if (!owns_window()) {\n      return;\n    }\n\n    // Skip application setup if this isn't the first instance of this class\n    // because the launch event is only sent once.\n    if (!get_and_set_is_first_instance()) {\n      window_init_proceed();\n      return;\n    }\n\n    m_app_delegate = create_app_delegate();\n    set_associated_webview(m_app_delegate, this);\n    NSApplication_set_delegate(m_app, m_app_delegate);\n\n    // Start the main run loop so that the app delegate gets the\n    // NSApplicationDidFinishLaunchingNotification notification after the run\n    // loop has started in order to perform further initialization.\n    // We need to return from this constructor so this run loop is only\n    // temporary.\n    NSApplication_run(m_app);\n  }\n  void window_init_proceed() {\n    objc::autoreleasepool arp;\n\n    m_window = objc::retain(NSWindow_withContentRect(\n        NSRectMake(0, 0, 0, 0), NSWindowStyleMaskTitled, NSBackingStoreBuffered,\n        false));\n    m_window_delegate = create_window_delegate();\n    set_associated_webview(m_window_delegate, this);\n    NSWindow_set_delegate(m_window, m_window_delegate);\n    on_window_created();\n  }\n\n  noresult window_show() {\n    objc::autoreleasepool arp;\n    if (m_is_window_shown) {\n      return {};\n    }\n    m_is_window_shown = true;\n    return {};\n  }\n\n  void run_event_loop_while(std::function<bool()> fn) override {\n    objc::autoreleasepool arp;\n    while (fn()) {\n      objc::autoreleasepool arp2;\n      if (auto event{NSApplication_nextEventMatchingMask(\n              m_app, NSEventMaskAny, nullptr,\n              NSRunLoopMode::NSDefaultRunLoopMode(), true)}) {\n        NSApplication_sendEvent(m_app, event);\n      }\n    }\n  }\n\n  id m_app{};\n  id m_app_delegate{};\n  id m_window_delegate{};\n  id m_window{};\n  id m_widget{};\n  id m_webview{};\n  id m_manager{};\n  bool m_is_window_shown{};\n};\n\n} // namespace cocoa_webkit\n} // namespace detail\n\nusing browser_engine = detail::cocoa_webkit::cocoa_wkwebview_engine;\n\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_COCOA_WEBKIT_HH\n"
  },
  {
    "path": "core/include/webview/detail/backends/gtk_webkitgtk.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH\n#define WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n\n//\n// ====================================================================\n//\n// This implementation uses webkit2gtk backend. It requires GTK and\n// WebKitGTK libraries. Proper compiler flags can be retrieved via:\n//\n//   pkg-config --cflags --libs gtk4 webkitgtk-6.0\n//   pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.1\n//   pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0\n//\n// ====================================================================\n//\n\n#include \"../../errors.hh\"\n#include \"../../types.hh\"\n#include \"../engine_base.hh\"\n#include \"../platform/linux/gtk/compat.hh\"\n#include \"../platform/linux/webkitgtk/compat.hh\"\n#include \"../platform/linux/webkitgtk/dmabuf.hh\"\n#include \"../user_script.hh\"\n\n#include <functional>\n#include <list>\n#include <memory>\n#include <string>\n\n#include <gtk/gtk.h>\n\n#if GTK_MAJOR_VERSION >= 4\n\n#include <jsc/jsc.h>\n#include <webkit/webkit.h>\n\n#elif GTK_MAJOR_VERSION >= 3\n\n#include <JavaScriptCore/JavaScript.h>\n#include <webkit2/webkit2.h>\n\n#endif\n\n#include <fcntl.h>\n#include <sys/stat.h>\n\nnamespace webview {\nnamespace detail {\n\nclass user_script::impl {\npublic:\n  impl(WebKitUserScript *script) : m_script{script} {\n    webkit_user_script_ref(script);\n  }\n\n  ~impl() { webkit_user_script_unref(m_script); }\n\n  impl(const impl &) = delete;\n  impl &operator=(const impl &) = delete;\n  impl(impl &&) = delete;\n  impl &operator=(impl &&) = delete;\n\n  WebKitUserScript *get_native() const { return m_script; }\n\nprivate:\n  WebKitUserScript *m_script{};\n};\n\nclass gtk_webkit_engine : public engine_base {\npublic:\n  gtk_webkit_engine(bool debug, void *window) : engine_base{!window} {\n    window_init(window);\n    window_settings(debug);\n    dispatch_size_default();\n  }\n\n  gtk_webkit_engine(const gtk_webkit_engine &) = delete;\n  gtk_webkit_engine &operator=(const gtk_webkit_engine &) = delete;\n  gtk_webkit_engine(gtk_webkit_engine &&) = delete;\n  gtk_webkit_engine &operator=(gtk_webkit_engine &&) = delete;\n\n  virtual ~gtk_webkit_engine() {\n    if (m_window) {\n      if (owns_window()) {\n        // Disconnect handlers to avoid callbacks invoked during destruction.\n        g_signal_handlers_disconnect_by_data(GTK_WINDOW(m_window), this);\n        gtk_window_close(GTK_WINDOW(m_window));\n        on_window_destroyed(true);\n      } else {\n        gtk_compat::window_remove_child(GTK_WINDOW(m_window),\n                                        GTK_WIDGET(m_webview));\n      }\n    }\n    if (m_webview) {\n      g_object_unref(m_webview);\n    }\n    if (owns_window()) {\n      // Needed for the window to close immediately.\n      deplete_run_loop_event_queue();\n    }\n  }\n\nprotected:\n  result<void *> window_impl() override {\n    if (m_window) {\n      return m_window;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  result<void *> widget_impl() override {\n    if (m_webview) {\n      return m_webview;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  result<void *> browser_controller_impl() override {\n    if (m_webview) {\n      return m_webview;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n\n  noresult run_impl() override {\n    m_stop_run_loop = false;\n    while (!m_stop_run_loop) {\n      g_main_context_iteration(nullptr, TRUE);\n    }\n    return {};\n  }\n\n  noresult terminate_impl() override {\n    return dispatch_impl([&] { m_stop_run_loop = true; });\n  }\n\n  noresult dispatch_impl(std::function<void()> f) override {\n    g_idle_add_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)([](void *fn) -> int {\n                      (*static_cast<dispatch_fn_t *>(fn))();\n                      return G_SOURCE_REMOVE;\n                    }),\n                    new std::function<void()>(f),\n                    [](void *fn) { delete static_cast<dispatch_fn_t *>(fn); });\n    return {};\n  }\n\n  noresult set_title_impl(const std::string &title) override {\n    gtk_window_set_title(GTK_WINDOW(m_window), title.c_str());\n    return {};\n  }\n\n  noresult set_size_impl(int width, int height, webview_hint_t hints) override {\n    gtk_window_set_resizable(GTK_WINDOW(m_window), hints != WEBVIEW_HINT_FIXED);\n    if (hints == WEBVIEW_HINT_NONE || hints == WEBVIEW_HINT_FIXED) {\n      gtk_compat::window_set_size(GTK_WINDOW(m_window), width, height);\n    } else if (hints == WEBVIEW_HINT_MIN) {\n      gtk_widget_set_size_request(m_window, width, height);\n    } else if (hints == WEBVIEW_HINT_MAX) {\n      gtk_compat::window_set_max_size(GTK_WINDOW(m_window), width, height);\n    } else {\n      return error_info{WEBVIEW_ERROR_INVALID_ARGUMENT, \"Invalid hint\"};\n    }\n    return window_show();\n  }\n\n  noresult navigate_impl(const std::string &url) override {\n    webkit_web_view_load_uri(WEBKIT_WEB_VIEW(m_webview), url.c_str());\n    return {};\n  }\n\n  noresult set_html_impl(const std::string &html) override {\n    webkit_web_view_load_html(WEBKIT_WEB_VIEW(m_webview), html.c_str(),\n                              nullptr);\n    return {};\n  }\n\n  noresult eval_impl(const std::string &js) override {\n    // URI is null before content has begun loading.\n    if (!webkit_web_view_get_uri(WEBKIT_WEB_VIEW(m_webview))) {\n      return {};\n    }\n#if (WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION >= 40) ||               \\\n    WEBKIT_MAJOR_VERSION > 2\n    webkit_web_view_evaluate_javascript(WEBKIT_WEB_VIEW(m_webview), js.c_str(),\n                                        static_cast<gssize>(js.size()), nullptr,\n                                        nullptr, nullptr, nullptr, nullptr);\n#else\n    webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(m_webview), js.c_str(),\n                                   nullptr, nullptr, nullptr);\n#endif\n    return {};\n  }\n\n  user_script add_user_script_impl(const std::string &js) override {\n    auto *wk_script = webkit_user_script_new(\n        js.c_str(), WEBKIT_USER_CONTENT_INJECT_TOP_FRAME,\n        WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, nullptr, nullptr);\n    webkit_user_content_manager_add_script(m_user_content_manager, wk_script);\n    user_script script{\n        js, user_script::impl_ptr{new user_script::impl{wk_script},\n                                  [](user_script::impl *p) { delete p; }}};\n    webkit_user_script_unref(wk_script);\n    return script;\n  }\n\n  void remove_all_user_scripts_impl(\n      const std::list<user_script> & /*scripts*/) override {\n    webkit_user_content_manager_remove_all_scripts(m_user_content_manager);\n  }\n\n  bool are_user_scripts_equal_impl(const user_script &first,\n                                   const user_script &second) override {\n    auto *wk_first = first.get_impl().get_native();\n    auto *wk_second = second.get_impl().get_native();\n    return wk_first == wk_second;\n  }\n\nprivate:\n#if GTK_MAJOR_VERSION >= 4\n  static char *get_string_from_js_result(JSCValue *r) {\n    return jsc_value_to_string(r);\n  }\n#else\n  static char *get_string_from_js_result(WebKitJavascriptResult *r) {\n    char *s;\n#if (WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION >= 22) ||               \\\n    WEBKIT_MAJOR_VERSION > 2\n    JSCValue *value = webkit_javascript_result_get_js_value(r);\n    s = jsc_value_to_string(value);\n#else\n    JSGlobalContextRef ctx = webkit_javascript_result_get_global_context(r);\n    JSValueRef value = webkit_javascript_result_get_value(r);\n    JSStringRef js = JSValueToStringCopy(ctx, value, nullptr);\n    size_t n = JSStringGetMaximumUTF8CStringSize(js);\n    s = g_new(char, n);\n    JSStringGetUTF8CString(js, s, n);\n    JSStringRelease(js);\n#endif\n    return s;\n  }\n#endif\n\n  void window_init(void *window) {\n    m_window = static_cast<GtkWidget *>(window);\n    if (owns_window()) {\n      if (!gtk_compat::init_check()) {\n        throw exception{WEBVIEW_ERROR_UNSPECIFIED, \"GTK init failed\"};\n      }\n      m_window = gtk_compat::window_new();\n      on_window_created();\n      auto on_window_destroy = +[](GtkWidget *, gpointer arg) {\n        auto *w = static_cast<gtk_webkit_engine *>(arg);\n        w->m_window = nullptr;\n        w->on_window_destroyed();\n      };\n      g_signal_connect(G_OBJECT(m_window), \"destroy\",\n                       G_CALLBACK(on_window_destroy), this);\n    }\n    webkit_dmabuf::apply_webkit_dmabuf_workaround();\n    // Initialize webview widget\n    m_webview = webkit_web_view_new();\n    g_object_ref_sink(m_webview);\n    WebKitUserContentManager *manager = m_user_content_manager =\n        webkit_web_view_get_user_content_manager(WEBKIT_WEB_VIEW(m_webview));\n    webkitgtk_compat::connect_script_message_received(\n        manager, \"__webview__\",\n        [this](WebKitUserContentManager *, const std::string &r) {\n          on_message(r);\n        });\n    webkitgtk_compat::user_content_manager_register_script_message_handler(\n        manager, \"__webview__\");\n    add_init_script(\"function(message) {\\n\\\n  return window.webkit.messageHandlers.__webview__.postMessage(message);\\n\\\n}\");\n  }\n\n  void window_settings(bool debug) {\n    WebKitSettings *settings =\n        webkit_web_view_get_settings(WEBKIT_WEB_VIEW(m_webview));\n    webkit_settings_set_javascript_can_access_clipboard(settings, true);\n    if (debug) {\n      webkit_settings_set_enable_write_console_messages_to_stdout(settings,\n                                                                  true);\n      webkit_settings_set_enable_developer_extras(settings, true);\n    }\n  }\n\n  noresult window_show() {\n    if (m_is_window_shown) {\n      return {};\n    }\n    gtk_compat::window_set_child(GTK_WINDOW(m_window), GTK_WIDGET(m_webview));\n    gtk_compat::widget_set_visible(GTK_WIDGET(m_webview), true);\n\n    if (owns_window()) {\n      gtk_widget_grab_focus(GTK_WIDGET(m_webview));\n      gtk_compat::widget_set_visible(GTK_WIDGET(m_window), true);\n    }\n    m_is_window_shown = true;\n    return {};\n  }\n\n  void run_event_loop_while(std::function<bool()> fn) override {\n    while (fn()) {\n      g_main_context_iteration(nullptr, TRUE);\n    }\n  }\n\n  GtkWidget *m_window{};\n  GtkWidget *m_webview{};\n  WebKitUserContentManager *m_user_content_manager{};\n  bool m_stop_run_loop{};\n  bool m_is_window_shown{};\n};\n\n} // namespace detail\n\nusing browser_engine = detail::gtk_webkit_engine;\n\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH\n"
  },
  {
    "path": "core/include/webview/detail/backends/win32_edge.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_WIN32_EDGE_HH\n#define WEBVIEW_BACKENDS_WIN32_EDGE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)\n\n//\n// ====================================================================\n//\n// This implementation uses Win32 API to create a native window. It\n// uses Edge/Chromium webview2 backend as a browser engine.\n//\n// ====================================================================\n//\n\n#include \"../../errors.hh\"\n#include \"../../types.hh\"\n#include \"../engine_base.hh\"\n#include \"../native_library.hh\"\n#include \"../platform/windows/com_init_wrapper.hh\"\n#include \"../platform/windows/dpi.hh\"\n#include \"../platform/windows/iid.hh\"\n#include \"../platform/windows/reg_key.hh\"\n#include \"../platform/windows/theme.hh\"\n#include \"../platform/windows/version.hh\"\n#include \"../platform/windows/webview2/loader.hh\"\n#include \"../user_script.hh\"\n#include \"../utility/string.hh\"\n\n#include <atomic>\n#include <cstdlib>\n#include <functional>\n#include <list>\n#include <memory>\n#include <utility>\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#include <objbase.h>\n#include <shlobj.h>\n#include <shlwapi.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"ole32.lib\")\n#pragma comment(lib, \"shell32.lib\")\n#pragma comment(lib, \"shlwapi.lib\")\n#pragma comment(lib, \"user32.lib\")\n#pragma comment(lib, \"version.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\nusing msg_cb_t = std::function<void(const std::string)>;\n\nclass webview2_com_handler\n    : public ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler,\n      public ICoreWebView2CreateCoreWebView2ControllerCompletedHandler,\n      public ICoreWebView2WebMessageReceivedEventHandler,\n      public ICoreWebView2PermissionRequestedEventHandler {\n  using webview2_com_handler_cb_t =\n      std::function<void(ICoreWebView2Controller *, ICoreWebView2 *webview)>;\n\npublic:\n  webview2_com_handler(HWND hwnd, msg_cb_t msgCb, webview2_com_handler_cb_t cb)\n      : m_window(hwnd), m_msgCb(msgCb), m_cb(cb) {}\n\n  virtual ~webview2_com_handler() = default;\n  webview2_com_handler(const webview2_com_handler &other) = delete;\n  webview2_com_handler &operator=(const webview2_com_handler &other) = delete;\n  webview2_com_handler(webview2_com_handler &&other) = delete;\n  webview2_com_handler &operator=(webview2_com_handler &&other) = delete;\n\n  ULONG STDMETHODCALLTYPE AddRef() { return ++m_ref_count; }\n  ULONG STDMETHODCALLTYPE Release() {\n    if (m_ref_count > 1) {\n      return --m_ref_count;\n    }\n    delete this;\n    return 0;\n  }\n  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv) {\n    using namespace mswebview2::cast_info;\n\n    if (!ppv) {\n      return E_POINTER;\n    }\n\n    // All of the COM interfaces we implement should be added here regardless\n    // of whether they are required.\n    // This is just to be on the safe side in case the WebView2 Runtime ever\n    // requests a pointer to an interface we implement.\n    // The WebView2 Runtime must at the very least be able to get a pointer to\n    // ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler when we use\n    // our custom WebView2 loader implementation, and observations have shown\n    // that it is the only interface requested in this case. None have been\n    // observed to be requested when using the official WebView2 loader.\n\n    if (cast_if_equal_iid(this, riid, controller_completed, ppv) ||\n        cast_if_equal_iid(this, riid, environment_completed, ppv) ||\n        cast_if_equal_iid(this, riid, message_received, ppv) ||\n        cast_if_equal_iid(this, riid, permission_requested, ppv)) {\n      return S_OK;\n    }\n\n    return E_NOINTERFACE;\n  }\n  HRESULT STDMETHODCALLTYPE Invoke(HRESULT res, ICoreWebView2Environment *env) {\n    if (SUCCEEDED(res)) {\n      res = env->CreateCoreWebView2Controller(m_window, this);\n      if (SUCCEEDED(res)) {\n        return S_OK;\n      }\n    }\n    try_create_environment();\n    return S_OK;\n  }\n  HRESULT STDMETHODCALLTYPE Invoke(HRESULT res,\n                                   ICoreWebView2Controller *controller) {\n    if (FAILED(res)) {\n      // See try_create_environment() regarding\n      // HRESULT_FROM_WIN32(ERROR_INVALID_STATE).\n      // The result is E_ABORT if the parent window has been destroyed already.\n      switch (res) {\n      case HRESULT_FROM_WIN32(ERROR_INVALID_STATE):\n      case E_ABORT:\n        return S_OK;\n      }\n      try_create_environment();\n      return S_OK;\n    }\n\n    ICoreWebView2 *webview;\n    ::EventRegistrationToken token;\n    controller->get_CoreWebView2(&webview);\n    webview->add_WebMessageReceived(this, &token);\n    webview->add_PermissionRequested(this, &token);\n\n    m_cb(controller, webview);\n    return S_OK;\n  }\n  HRESULT STDMETHODCALLTYPE\n  Invoke(ICoreWebView2 * /*sender*/,\n         ICoreWebView2WebMessageReceivedEventArgs *args) {\n    LPWSTR message{};\n    auto res = args->TryGetWebMessageAsString(&message);\n    if (SUCCEEDED(res)) {\n      m_msgCb(narrow_string(message));\n    }\n\n    CoTaskMemFree(message);\n    return S_OK;\n  }\n  HRESULT STDMETHODCALLTYPE\n  Invoke(ICoreWebView2 * /*sender*/,\n         ICoreWebView2PermissionRequestedEventArgs *args) {\n    COREWEBVIEW2_PERMISSION_KIND kind;\n    args->get_PermissionKind(&kind);\n    if (kind == COREWEBVIEW2_PERMISSION_KIND_CLIPBOARD_READ) {\n      args->put_State(COREWEBVIEW2_PERMISSION_STATE_ALLOW);\n    }\n    return S_OK;\n  }\n\n  // Set the function that will perform the initiating logic for creating\n  // the WebView2 environment.\n  void set_attempt_handler(std::function<HRESULT()> attempt_handler) noexcept {\n    m_attempt_handler = attempt_handler;\n  }\n\n  // Retry creating a WebView2 environment.\n  // The initiating logic for creating the environment is defined by the\n  // caller of set_attempt_handler().\n  void try_create_environment() noexcept {\n    // WebView creation fails with HRESULT_FROM_WIN32(ERROR_INVALID_STATE) if\n    // a running instance using the same user data folder exists, and the\n    // Environment objects have different EnvironmentOptions.\n    // Source: https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment?view=webview2-1.0.1150.38\n    if (m_attempts < m_max_attempts) {\n      ++m_attempts;\n      auto res = m_attempt_handler();\n      if (SUCCEEDED(res)) {\n        return;\n      }\n      // Not entirely sure if this error code only applies to\n      // CreateCoreWebView2Controller so we check here as well.\n      if (res == HRESULT_FROM_WIN32(ERROR_INVALID_STATE)) {\n        return;\n      }\n      // Wait for m_sleep_ms before trying again.\n      Sleep(m_sleep_ms);\n      try_create_environment();\n      return;\n    }\n    // Give up.\n    m_cb(nullptr, nullptr);\n  }\n\nprivate:\n  HWND m_window;\n  msg_cb_t m_msgCb;\n  webview2_com_handler_cb_t m_cb;\n  std::atomic<ULONG> m_ref_count{1};\n  std::function<HRESULT()> m_attempt_handler;\n  unsigned int m_max_attempts = 60;\n  unsigned int m_sleep_ms = 200;\n  unsigned int m_attempts = 0;\n};\n\nclass webview2_user_script_added_handler\n    : public ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler {\npublic:\n  using callback_fn = std::function<void(HRESULT errorCode, LPCWSTR id)>;\n\n  webview2_user_script_added_handler(callback_fn cb) : m_cb{cb} {}\n\n  virtual ~webview2_user_script_added_handler() = default;\n  webview2_user_script_added_handler(\n      const webview2_user_script_added_handler &other) = delete;\n  webview2_user_script_added_handler &\n  operator=(const webview2_user_script_added_handler &other) = delete;\n  webview2_user_script_added_handler(\n      webview2_user_script_added_handler &&other) = delete;\n  webview2_user_script_added_handler &\n  operator=(webview2_user_script_added_handler &&other) = delete;\n\n  ULONG STDMETHODCALLTYPE AddRef() { return ++m_ref_count; }\n  ULONG STDMETHODCALLTYPE Release() {\n    if (m_ref_count > 1) {\n      return --m_ref_count;\n    }\n    delete this;\n    return 0;\n  }\n\n  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv) {\n    using namespace mswebview2::cast_info;\n\n    if (!ppv) {\n      return E_POINTER;\n    }\n\n    if (cast_if_equal_iid(this, riid,\n                          add_script_to_execute_on_document_created_completed,\n                          ppv)) {\n      return S_OK;\n    }\n\n    return E_NOINTERFACE;\n  }\n\n  HRESULT STDMETHODCALLTYPE Invoke(HRESULT res, LPCWSTR id) {\n    m_cb(res, id);\n    return S_OK;\n  }\n\nprivate:\n  callback_fn m_cb;\n  std::atomic<ULONG> m_ref_count{1};\n};\n\nclass user_script::impl {\npublic:\n  impl(const std::wstring &id, const std::wstring &code)\n      : m_id{id}, m_code{code} {}\n\n  impl(const impl &) = delete;\n  impl &operator=(const impl &) = delete;\n  impl(impl &&) = delete;\n  impl &operator=(impl &&) = delete;\n\n  const std::wstring &get_id() const { return m_id; }\n  const std::wstring &get_code() const { return m_code; }\n\nprivate:\n  std::wstring m_id;\n  std::wstring m_code;\n};\n\nclass win32_edge_engine : public engine_base {\npublic:\n  win32_edge_engine(bool debug, void *window) : engine_base{!window} {\n    window_init(window);\n    window_settings(debug);\n    dispatch_size_default();\n  }\n\n  virtual ~win32_edge_engine() {\n    if (m_com_handler) {\n      m_com_handler->Release();\n      m_com_handler = nullptr;\n    }\n    if (m_webview) {\n      m_webview->Release();\n      m_webview = nullptr;\n    }\n    if (m_controller) {\n      m_controller->Release();\n      m_controller = nullptr;\n    }\n    // Replace wndproc to avoid callbacks and other bad things during\n    // destruction.\n    auto wndproc = reinterpret_cast<LONG_PTR>(\n        +[](HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) -> LRESULT {\n          return DefWindowProcW(hwnd, msg, wp, lp);\n        });\n    if (m_widget) {\n      SetWindowLongPtrW(m_widget, GWLP_WNDPROC, wndproc);\n    }\n    if (m_window && owns_window()) {\n      SetWindowLongPtrW(m_window, GWLP_WNDPROC, wndproc);\n    }\n    if (m_widget) {\n      DestroyWindow(m_widget);\n      m_widget = nullptr;\n    }\n    if (m_window) {\n      if (owns_window()) {\n        DestroyWindow(m_window);\n        on_window_destroyed(true);\n      }\n      m_window = nullptr;\n    }\n    if (owns_window()) {\n      // Not strictly needed for windows to close immediately but aligns\n      // behavior across backends.\n      deplete_run_loop_event_queue();\n    }\n    // We need the message window in order to deplete the event queue.\n    if (m_message_window) {\n      SetWindowLongPtrW(m_message_window, GWLP_WNDPROC, wndproc);\n      DestroyWindow(m_message_window);\n      m_message_window = nullptr;\n    }\n  }\n\n  win32_edge_engine(const win32_edge_engine &other) = delete;\n  win32_edge_engine &operator=(const win32_edge_engine &other) = delete;\n  win32_edge_engine(win32_edge_engine &&other) = delete;\n  win32_edge_engine &operator=(win32_edge_engine &&other) = delete;\n\nprotected:\n  noresult run_impl() override {\n    MSG msg;\n    while (GetMessageW(&msg, nullptr, 0, 0) > 0) {\n      TranslateMessage(&msg);\n      DispatchMessageW(&msg);\n    }\n    return {};\n  }\n  result<void *> window_impl() override {\n    if (m_window) {\n      return m_window;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n  result<void *> widget_impl() override {\n    if (m_widget) {\n      return m_widget;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n  result<void *> browser_controller_impl() override {\n    if (m_controller) {\n      return m_controller;\n    }\n    return error_info{WEBVIEW_ERROR_INVALID_STATE};\n  }\n  noresult terminate_impl() override {\n    PostQuitMessage(0);\n    return {};\n  }\n  noresult dispatch_impl(dispatch_fn_t f) override {\n    PostMessageW(m_message_window, WM_APP, 0, (LPARAM) new dispatch_fn_t(f));\n    return {};\n  }\n\n  noresult set_title_impl(const std::string &title) override {\n    SetWindowTextW(m_window, widen_string(title).c_str());\n    return {};\n  }\n\n  noresult set_size_impl(int width, int height, webview_hint_t hints) override {\n    auto style = GetWindowLong(m_window, GWL_STYLE);\n    if (hints == WEBVIEW_HINT_FIXED) {\n      style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);\n    } else {\n      style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);\n    }\n    SetWindowLong(m_window, GWL_STYLE, style);\n\n    if (hints == WEBVIEW_HINT_MAX) {\n      m_maxsz.x = width;\n      m_maxsz.y = height;\n    } else if (hints == WEBVIEW_HINT_MIN) {\n      m_minsz.x = width;\n      m_minsz.y = height;\n    } else {\n      auto dpi = get_window_dpi(m_window);\n      m_dpi = dpi;\n      auto scaled_size =\n          scale_size(width, height, get_default_window_dpi(), dpi);\n      auto frame_size =\n          make_window_frame_size(m_window, scaled_size.cx, scaled_size.cy, dpi);\n      SetWindowPos(m_window, nullptr, 0, 0, frame_size.cx, frame_size.cy,\n                   SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE |\n                       SWP_FRAMECHANGED);\n    }\n    return window_show();\n  }\n\n  noresult navigate_impl(const std::string &url) override {\n    auto wurl = widen_string(url);\n    m_webview->Navigate(wurl.c_str());\n    return {};\n  }\n\n  noresult eval_impl(const std::string &js) override {\n    // TODO: Skip if no content has begun loading yet. Can't check with\n    //       ICoreWebView2::get_Source because it returns \"about:blank\".\n    auto wjs = widen_string(js);\n    m_webview->ExecuteScript(wjs.c_str(), nullptr);\n    return {};\n  }\n\n  noresult set_html_impl(const std::string &html) override {\n    m_webview->NavigateToString(widen_string(html).c_str());\n    return {};\n  }\n\n  user_script add_user_script_impl(const std::string &js) override {\n    auto wjs = widen_string(js);\n    std::wstring script_id;\n    bool done{};\n    webview2_user_script_added_handler handler{[&](HRESULT res, LPCWSTR id) {\n      if (SUCCEEDED(res)) {\n        script_id = id;\n      }\n      done = true;\n    }};\n    auto res =\n        m_webview->AddScriptToExecuteOnDocumentCreated(wjs.c_str(), &handler);\n    if (SUCCEEDED(res)) {\n      // We want to guard against executing the default `set_size` prematurely\n      set_default_size_guard(true);\n      // Sadly we need to pump the event loop in order to get the script ID.\n      run_event_loop_while([&] { return !done; });\n      // The user's `set_size` may have been executed from the depleted event queue,\n      // and if so, guard against putting the default `set_size` back onto the queue.\n      if (!m_is_window_shown) {\n        set_default_size_guard(false);\n        dispatch_size_default();\n      }\n    }\n    // TODO: There's a non-zero chance that we didn't get the script ID.\n    //       We need to convey the error somehow.\n    return user_script{\n        js, user_script::impl_ptr{new user_script::impl{script_id, wjs},\n                                  [](user_script::impl *p) { delete p; }}};\n  }\n\n  void\n  remove_all_user_scripts_impl(const std::list<user_script> &scripts) override {\n    for (const auto &script : scripts) {\n      const auto &id = script.get_impl().get_id();\n      m_webview->RemoveScriptToExecuteOnDocumentCreated(id.c_str());\n    }\n  }\n\n  bool are_user_scripts_equal_impl(const user_script &first,\n                                   const user_script &second) override {\n    const auto &first_id = first.get_impl().get_id();\n    const auto &second_id = second.get_impl().get_id();\n    return first_id == second_id;\n  }\n\nprivate:\n  void window_init(void *window) {\n    if (!is_webview2_available()) {\n      throw exception{WEBVIEW_ERROR_MISSING_DEPENDENCY,\n                      \"WebView2 is unavailable\"};\n    }\n\n    HINSTANCE hInstance = GetModuleHandle(nullptr);\n\n    if (owns_window()) {\n      m_com_init = {COINIT_APARTMENTTHREADED};\n      enable_dpi_awareness();\n\n      HICON icon = (HICON)LoadImage(\n          hInstance, IDI_APPLICATION, IMAGE_ICON, GetSystemMetrics(SM_CXICON),\n          GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);\n\n      // Create a top-level window.\n      WNDCLASSEXW wc;\n      ZeroMemory(&wc, sizeof(WNDCLASSEX));\n      wc.cbSize = sizeof(WNDCLASSEX);\n      wc.hInstance = hInstance;\n      wc.lpszClassName = L\"webview\";\n      wc.hIcon = icon;\n      wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,\n                                     LPARAM lp) -> LRESULT {\n        win32_edge_engine *w{};\n\n        if (msg == WM_NCCREATE) {\n          auto *lpcs{reinterpret_cast<LPCREATESTRUCT>(lp)};\n          w = static_cast<win32_edge_engine *>(lpcs->lpCreateParams);\n          w->m_window = hwnd;\n          SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(w));\n          enable_non_client_dpi_scaling_if_needed(hwnd);\n          apply_window_theme(hwnd);\n        } else {\n          w = reinterpret_cast<win32_edge_engine *>(\n              GetWindowLongPtrW(hwnd, GWLP_USERDATA));\n        }\n\n        if (!w) {\n          return DefWindowProcW(hwnd, msg, wp, lp);\n        }\n\n        switch (msg) {\n        case WM_SIZE:\n          w->resize_widget();\n          break;\n        case WM_CLOSE:\n          DestroyWindow(hwnd);\n          break;\n        case WM_DESTROY:\n          w->m_window = nullptr;\n          SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);\n          w->on_window_destroyed();\n          break;\n        case WM_GETMINMAXINFO: {\n          auto lpmmi = (LPMINMAXINFO)lp;\n          if (w->m_maxsz.x > 0 && w->m_maxsz.y > 0) {\n            lpmmi->ptMaxSize = w->m_maxsz;\n            lpmmi->ptMaxTrackSize = w->m_maxsz;\n          }\n          if (w->m_minsz.x > 0 && w->m_minsz.y > 0) {\n            lpmmi->ptMinTrackSize = w->m_minsz;\n          }\n        } break;\n        case 0x02E4 /*WM_GETDPISCALEDSIZE*/: {\n          auto dpi = static_cast<int>(wp);\n          auto *size{reinterpret_cast<SIZE *>(lp)};\n          *size = w->get_scaled_size(w->m_dpi, dpi);\n          return TRUE;\n        }\n        case 0x02E0 /*WM_DPICHANGED*/: {\n          // Windows 10: The size we get here is exactly what we supplied to WM_GETDPISCALEDSIZE.\n          // Windows 11: The size we get here is NOT what we supplied to WM_GETDPISCALEDSIZE.\n          // Due to this difference, don't use the suggested bounds.\n          auto dpi = static_cast<int>(HIWORD(wp));\n          w->on_dpi_changed(dpi);\n          break;\n        }\n        case WM_SETTINGCHANGE: {\n          auto *area = reinterpret_cast<const wchar_t *>(lp);\n          if (area) {\n            w->on_system_setting_change(area);\n          }\n          break;\n        }\n        case WM_ACTIVATE:\n          if (LOWORD(wp) != WA_INACTIVE) {\n            w->focus_webview();\n          }\n          break;\n        default:\n          return DefWindowProcW(hwnd, msg, wp, lp);\n        }\n        return 0;\n      });\n      RegisterClassExW(&wc);\n\n      CreateWindowW(L\"webview\", L\"\", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,\n                    CW_USEDEFAULT, 0, 0, nullptr, nullptr, hInstance, this);\n      if (!m_window) {\n        throw exception{WEBVIEW_ERROR_INVALID_STATE, \"Window is null\"};\n      }\n      on_window_created();\n\n      m_dpi = get_window_dpi(m_window);\n    } else {\n      m_window = IsWindow(static_cast<HWND>(window))\n                     ? static_cast<HWND>(window)\n                     : *(static_cast<HWND *>(window));\n      m_dpi = get_window_dpi(m_window);\n    }\n    // Create a window that WebView2 will be embedded into.\n    WNDCLASSEXW widget_wc{};\n    widget_wc.cbSize = sizeof(WNDCLASSEX);\n    widget_wc.hInstance = hInstance;\n    widget_wc.lpszClassName = L\"webview_widget\";\n    widget_wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,\n                                          LPARAM lp) -> LRESULT {\n      win32_edge_engine *w{};\n\n      if (msg == WM_NCCREATE) {\n        auto *lpcs{reinterpret_cast<LPCREATESTRUCT>(lp)};\n        w = static_cast<win32_edge_engine *>(lpcs->lpCreateParams);\n        w->m_widget = hwnd;\n        SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(w));\n      } else {\n        w = reinterpret_cast<win32_edge_engine *>(\n            GetWindowLongPtrW(hwnd, GWLP_USERDATA));\n      }\n\n      if (!w) {\n        return DefWindowProcW(hwnd, msg, wp, lp);\n      }\n\n      switch (msg) {\n      case WM_SIZE:\n        w->resize_webview();\n        break;\n      case WM_DESTROY:\n        w->m_widget = nullptr;\n        SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);\n        break;\n      default:\n        return DefWindowProcW(hwnd, msg, wp, lp);\n      }\n      return 0;\n    });\n    RegisterClassExW(&widget_wc);\n    CreateWindowExW(WS_EX_CONTROLPARENT, L\"webview_widget\", nullptr, WS_CHILD,\n                    0, 0, 0, 0, m_window, nullptr, hInstance, this);\n    if (!m_widget) {\n      throw exception{WEBVIEW_ERROR_INVALID_STATE, \"Widget window is null\"};\n    }\n\n    // Create a message-only window for internal messaging.\n    WNDCLASSEXW message_wc{};\n    message_wc.cbSize = sizeof(WNDCLASSEX);\n    message_wc.hInstance = hInstance;\n    message_wc.lpszClassName = L\"webview_message\";\n    message_wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,\n                                           LPARAM lp) -> LRESULT {\n      win32_edge_engine *w{};\n\n      if (msg == WM_NCCREATE) {\n        auto *lpcs{reinterpret_cast<LPCREATESTRUCT>(lp)};\n        w = static_cast<win32_edge_engine *>(lpcs->lpCreateParams);\n        w->m_message_window = hwnd;\n        SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(w));\n      } else {\n        w = reinterpret_cast<win32_edge_engine *>(\n            GetWindowLongPtrW(hwnd, GWLP_USERDATA));\n      }\n\n      if (!w) {\n        return DefWindowProcW(hwnd, msg, wp, lp);\n      }\n\n      switch (msg) {\n      case WM_APP:\n        if (auto f = (dispatch_fn_t *)(lp)) {\n          (*f)();\n          delete f;\n        }\n        break;\n      case WM_DESTROY:\n        w->m_message_window = nullptr;\n        SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);\n        break;\n      default:\n        return DefWindowProcW(hwnd, msg, wp, lp);\n      }\n      return 0;\n    });\n    RegisterClassExW(&message_wc);\n    CreateWindowExW(0, L\"webview_message\", nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE,\n                    nullptr, hInstance, this);\n    if (!m_message_window) {\n      throw exception{WEBVIEW_ERROR_INVALID_STATE, \"Message window is null\"};\n    }\n  }\n\n  void window_settings(bool debug) {\n    auto cb =\n        std::bind(&win32_edge_engine::on_message, this, std::placeholders::_1);\n    embed(m_widget, debug, cb).ensure_ok();\n  }\n\n  noresult window_show() {\n    if (owns_window() && !m_is_window_shown) {\n      ShowWindow(m_window, SW_SHOW);\n      UpdateWindow(m_window);\n      SetFocus(m_window);\n      m_is_window_shown = true;\n    }\n    return {};\n  }\n  noresult embed(HWND wnd, bool debug, msg_cb_t cb) {\n    std::atomic_flag flag = ATOMIC_FLAG_INIT;\n    flag.test_and_set();\n\n    wchar_t currentExePath[MAX_PATH];\n    GetModuleFileNameW(nullptr, currentExePath, MAX_PATH);\n    wchar_t *currentExeName = PathFindFileNameW(currentExePath);\n\n    wchar_t dataPath[MAX_PATH];\n    if (!SUCCEEDED(\n            SHGetFolderPathW(nullptr, CSIDL_APPDATA, nullptr, 0, dataPath))) {\n      return error_info{WEBVIEW_ERROR_UNSPECIFIED, \"SHGetFolderPathW failed\"};\n    }\n    wchar_t userDataFolder[MAX_PATH];\n    PathCombineW(userDataFolder, dataPath, currentExeName);\n\n    m_com_handler = new webview2_com_handler(\n        wnd, cb,\n        [&](ICoreWebView2Controller *controller, ICoreWebView2 *webview) {\n          if (!controller || !webview) {\n            flag.clear();\n            return;\n          }\n          controller->AddRef();\n          webview->AddRef();\n          m_controller = controller;\n          m_webview = webview;\n          flag.clear();\n        });\n\n    m_com_handler->set_attempt_handler([&] {\n      return m_webview2_loader.create_environment_with_options(\n          nullptr, userDataFolder, nullptr, m_com_handler);\n    });\n    m_com_handler->try_create_environment();\n\n    // Pump the message loop until WebView2 has finished initialization.\n    bool got_quit_msg = false;\n    MSG msg;\n    while (flag.test_and_set() && GetMessageW(&msg, nullptr, 0, 0) >= 0) {\n      if (msg.message == WM_QUIT) {\n        got_quit_msg = true;\n        break;\n      }\n      TranslateMessage(&msg);\n      DispatchMessageW(&msg);\n    }\n    if (got_quit_msg) {\n      return error_info{WEBVIEW_ERROR_CANCELED};\n    }\n    if (!m_controller || !m_webview) {\n      return error_info{WEBVIEW_ERROR_INVALID_STATE};\n    }\n    ICoreWebView2Settings *settings = nullptr;\n    auto res = m_webview->get_Settings(&settings);\n    if (res != S_OK) {\n      return error_info{WEBVIEW_ERROR_UNSPECIFIED, \"get_Settings failed\"};\n    }\n    res = settings->put_AreDevToolsEnabled(debug ? TRUE : FALSE);\n    if (res != S_OK) {\n      return error_info{WEBVIEW_ERROR_UNSPECIFIED,\n                        \"put_AreDevToolsEnabled failed\"};\n    }\n    res = settings->put_IsStatusBarEnabled(FALSE);\n    if (res != S_OK) {\n      return error_info{WEBVIEW_ERROR_UNSPECIFIED,\n                        \"put_IsStatusBarEnabled failed\"};\n    }\n    add_init_script(\"function(message) {\\n\\\n  return window.chrome.webview.postMessage(message);\\n\\\n}\");\n    resize_webview();\n    m_controller->put_IsVisible(TRUE);\n    ShowWindow(m_widget, SW_SHOW);\n    UpdateWindow(m_widget);\n    if (owns_window()) {\n      focus_webview();\n    }\n    return {};\n  }\n\n  void resize_widget() {\n    if (m_widget) {\n      RECT r{};\n      if (GetClientRect(GetParent(m_widget), &r)) {\n        MoveWindow(m_widget, r.left, r.top, r.right - r.left, r.bottom - r.top,\n                   TRUE);\n      }\n    }\n  }\n\n  void resize_webview() {\n    if (m_widget && m_controller) {\n      RECT bounds{};\n      if (GetClientRect(m_widget, &bounds)) {\n        m_controller->put_Bounds(bounds);\n      }\n    }\n  }\n\n  void focus_webview() {\n    if (m_controller) {\n      m_controller->MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);\n    }\n  }\n\n  bool is_webview2_available() const noexcept {\n    LPWSTR version_info = nullptr;\n    auto res = m_webview2_loader.get_available_browser_version_string(\n        nullptr, &version_info);\n    // The result will be equal to HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)\n    // if the WebView2 runtime is not installed.\n    auto ok = SUCCEEDED(res) && version_info;\n    if (version_info) {\n      CoTaskMemFree(version_info);\n    }\n    return ok;\n  }\n\n  void on_dpi_changed(int dpi) {\n    auto scaled_size = get_scaled_size(m_dpi, dpi);\n    auto frame_size =\n        make_window_frame_size(m_window, scaled_size.cx, scaled_size.cy, dpi);\n    SetWindowPos(m_window, nullptr, 0, 0, frame_size.cx, frame_size.cy,\n                 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_FRAMECHANGED);\n    m_dpi = dpi;\n  }\n\n  SIZE get_size() const {\n    RECT bounds;\n    GetClientRect(m_window, &bounds);\n    auto width = bounds.right - bounds.left;\n    auto height = bounds.bottom - bounds.top;\n    return {width, height};\n  }\n\n  SIZE get_scaled_size(int from_dpi, int to_dpi) const {\n    auto size = get_size();\n    return scale_size(size.cx, size.cy, from_dpi, to_dpi);\n  }\n\n  void on_system_setting_change(const wchar_t *area) {\n    // Detect light/dark mode change in system.\n    if (lstrcmpW(area, L\"ImmersiveColorSet\") == 0) {\n      apply_window_theme(m_window);\n    }\n  }\n\n  void run_event_loop_while(std::function<bool()> fn) override {\n    MSG msg;\n    while (fn() && GetMessageW(&msg, nullptr, 0, 0) > 0) {\n      TranslateMessage(&msg);\n      DispatchMessageW(&msg);\n    }\n  }\n\n  // The app is expected to call CoInitializeEx before\n  // CreateCoreWebView2EnvironmentWithOptions.\n  // Source: https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl#createcorewebview2environmentwithoptions\n  com_init_wrapper m_com_init;\n  HWND m_window = nullptr;\n  HWND m_widget = nullptr;\n  HWND m_message_window = nullptr;\n  POINT m_minsz = POINT{0, 0};\n  POINT m_maxsz = POINT{0, 0};\n  DWORD m_main_thread = GetCurrentThreadId();\n  ICoreWebView2 *m_webview = nullptr;\n  ICoreWebView2Controller *m_controller = nullptr;\n  webview2_com_handler *m_com_handler = nullptr;\n  mswebview2::loader m_webview2_loader;\n  int m_dpi{};\n  bool m_is_window_shown{};\n};\n\n} // namespace detail\n\nusing browser_engine = detail::win32_edge_engine;\n\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_WIN32_EDGE_HH\n"
  },
  {
    "path": "core/include/webview/detail/basic_result.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_BASIC_RESULT_HH\n#define WEBVIEW_DETAIL_BASIC_RESULT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"exceptions.hh\"\n#include \"optional.hh\"\n\n#include <utility>\n\nnamespace webview {\nnamespace detail {\n\ntemplate <typename Value, typename Error, typename Exception>\nclass basic_result {\npublic:\n  using value_type = Value;\n  using error_type = Error;\n  using exception_type = Exception;\n\n  basic_result() : basic_result(value_type{}) {}\n\n  basic_result(const value_type &value) : m_value{value} {}\n  basic_result(value_type &&value) : m_value{std::forward<value_type>(value)} {}\n\n  basic_result(const error_type &error) : m_error{error} {}\n  basic_result(error_type &&error) : m_error{std::forward<error_type>(error)} {}\n\n  bool ok() const { return has_value() && !has_error(); }\n  bool has_value() const { return m_value.has_value(); }\n  bool has_error() const { return m_error.has_value(); }\n\n  void ensure_ok() {\n    if (!ok()) {\n      throw exception_type{error()};\n    }\n  }\n\n  const value_type &value() const {\n    if (!has_value()) {\n      throw bad_access{};\n    }\n    return m_value.get();\n  }\n\n  const error_type &error() const {\n    if (!has_error()) {\n      throw bad_access{};\n    }\n    return m_error.get();\n  }\n\nprivate:\n  optional<value_type> m_value;\n  optional<error_type> m_error;\n};\n\ntemplate <typename Error, typename Exception>\nclass basic_result<void, Error, Exception> {\npublic:\n  using value_type = void;\n  using error_type = Error;\n  using exception_type = Exception;\n\n  basic_result() = default;\n\n  basic_result(error_type &&error) : m_error{std::forward<error_type>(error)} {}\n\n  bool ok() const { return !has_error(); }\n\n  bool has_error() const { return m_error.has_value(); }\n\n  void ensure_ok() {\n    if (!ok()) {\n      throw exception_type{error()};\n    }\n  }\n\n  const error_type &error() const {\n    if (!has_error()) {\n      throw bad_access{};\n    }\n    return m_error.get();\n  }\n\nprivate:\n  optional<error_type> m_error;\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_BASIC_RESULT_HH\n"
  },
  {
    "path": "core/include/webview/detail/engine_base.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_ENGINE_BASE_HH\n#define WEBVIEW_DETAIL_ENGINE_BASE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../errors.hh\"\n#include \"../types.h\"\n#include \"../types.hh\"\n#include \"json.hh\"\n#include \"user_script.hh\"\n\n#include <atomic>\n#include <functional>\n#include <list>\n#include <map>\n#include <string>\n\nnamespace webview {\nnamespace detail {\n\nclass engine_base {\npublic:\n  engine_base(bool owns_window) : m_owns_window{owns_window} {}\n\n  virtual ~engine_base() = default;\n\n  noresult navigate(const std::string &url) {\n    if (url.empty()) {\n      return navigate_impl(\"about:blank\");\n    }\n    return navigate_impl(url);\n  }\n\n  using binding_t = std::function<void(std::string, std::string, void *)>;\n  class binding_ctx_t {\n  public:\n    binding_ctx_t(binding_t callback, void *arg)\n        : m_callback(callback), m_arg(arg) {}\n    void call(std::string id, std::string args) const {\n      if (m_callback) {\n        m_callback(id, args, m_arg);\n      }\n    }\n\n  private:\n    // This function is called upon execution of the bound JS function\n    binding_t m_callback;\n    // This user-supplied argument is passed to the callback\n    void *m_arg;\n  };\n\n  using sync_binding_t = std::function<std::string(std::string)>;\n\n  // Synchronous bind\n  noresult bind(const std::string &name, sync_binding_t fn) {\n    auto wrapper = [this, fn](const std::string &id, const std::string &req,\n                              void * /*arg*/) { resolve(id, 0, fn(req)); };\n    return bind(name, wrapper, nullptr);\n  }\n\n  // Asynchronous bind\n  noresult bind(const std::string &name, binding_t fn, void *arg) {\n    // NOLINTNEXTLINE(readability-container-contains): contains() requires C++20\n    if (bindings.count(name) > 0) {\n      return error_info{WEBVIEW_ERROR_DUPLICATE};\n    }\n    bindings.emplace(name, binding_ctx_t(fn, arg));\n    replace_bind_script();\n    // Notify that a binding was created if the init script has already\n    // set things up.\n    eval(\"if (window.__webview__) {\\n\\\nwindow.__webview__.onBind(\" +\n         json_escape(name) + \")\\n\\\n}\");\n    return {};\n  }\n\n  noresult unbind(const std::string &name) {\n    auto found = bindings.find(name);\n    if (found == bindings.end()) {\n      return error_info{WEBVIEW_ERROR_NOT_FOUND};\n    }\n    bindings.erase(found);\n    replace_bind_script();\n    // Notify that a binding was created if the init script has already\n    // set things up.\n    eval(\"if (window.__webview__) {\\n\\\nwindow.__webview__.onUnbind(\" +\n         json_escape(name) + \")\\n\\\n}\");\n    return {};\n  }\n\n  noresult resolve(const std::string &id, int status,\n                   const std::string &result) {\n    // NOLINTNEXTLINE(modernize-avoid-bind): Lambda with move requires C++14\n    return dispatch(std::bind(\n        [id, status, this](std::string escaped_result) {\n          std::string js = \"window.__webview__.onReply(\" + json_escape(id) +\n                           \", \" + std::to_string(status) + \", \" +\n                           escaped_result + \")\";\n          eval(js);\n        },\n        result.empty() ? \"undefined\" : json_escape(result)));\n  }\n\n  result<void *> window() { return window_impl(); }\n  result<void *> widget() { return widget_impl(); }\n  result<void *> browser_controller() { return browser_controller_impl(); }\n  noresult run() { return run_impl(); }\n  noresult terminate() { return terminate_impl(); }\n  noresult dispatch(std::function<void()> f) { return dispatch_impl(f); }\n  noresult set_title(const std::string &title) { return set_title_impl(title); }\n\n  noresult set_size(int width, int height, webview_hint_t hints) {\n    auto res = set_size_impl(width, height, hints);\n    m_is_size_set = true;\n    return res;\n  }\n\n  noresult set_html(const std::string &html) { return set_html_impl(html); }\n\n  noresult init(const std::string &js) {\n    add_user_script(js);\n    return {};\n  }\n\n  noresult eval(const std::string &js) { return eval_impl(js); }\n\nprotected:\n  virtual noresult navigate_impl(const std::string &url) = 0;\n  virtual result<void *> window_impl() = 0;\n  virtual result<void *> widget_impl() = 0;\n  virtual result<void *> browser_controller_impl() = 0;\n  virtual noresult run_impl() = 0;\n  virtual noresult terminate_impl() = 0;\n  virtual noresult dispatch_impl(std::function<void()> f) = 0;\n  virtual noresult set_title_impl(const std::string &title) = 0;\n  virtual noresult set_size_impl(int width, int height,\n                                 webview_hint_t hints) = 0;\n  virtual noresult set_html_impl(const std::string &html) = 0;\n  virtual noresult eval_impl(const std::string &js) = 0;\n\n  virtual user_script *add_user_script(const std::string &js) {\n    return std::addressof(*m_user_scripts.emplace(m_user_scripts.end(),\n                                                  add_user_script_impl(js)));\n  }\n\n  virtual user_script add_user_script_impl(const std::string &js) = 0;\n\n  virtual void\n  remove_all_user_scripts_impl(const std::list<user_script> &scripts) = 0;\n\n  virtual bool are_user_scripts_equal_impl(const user_script &first,\n                                           const user_script &second) = 0;\n\n  virtual user_script *replace_user_script(const user_script &old_script,\n                                           const std::string &new_script_code) {\n    remove_all_user_scripts_impl(m_user_scripts);\n    user_script *old_script_ptr{};\n    for (auto &script : m_user_scripts) {\n      auto is_old_script = are_user_scripts_equal_impl(script, old_script);\n      script = add_user_script_impl(is_old_script ? new_script_code\n                                                  : script.get_code());\n      if (is_old_script) {\n        old_script_ptr = std::addressof(script);\n      }\n    }\n    return old_script_ptr;\n  }\n\n  void replace_bind_script() {\n    if (m_bind_script) {\n      m_bind_script = replace_user_script(*m_bind_script, create_bind_script());\n    } else {\n      m_bind_script = add_user_script(create_bind_script());\n    }\n  }\n\n  void add_init_script(const std::string &post_fn) {\n    add_user_script(create_init_script(post_fn));\n    m_is_init_script_added = true;\n  }\n\n  std::string create_init_script(const std::string &post_fn) {\n    auto js = std::string{} + \"(function() {\\n\\\n  'use strict';\\n\\\n  function generateId() {\\n\\\n    var crypto = window.crypto || window.msCrypto;\\n\\\n    var bytes = new Uint8Array(16);\\n\\\n    crypto.getRandomValues(bytes);\\n\\\n    return Array.prototype.slice.call(bytes).map(function(n) {\\n\\\n      var s = n.toString(16);\\n\\\n      return ((s.length % 2) == 1 ? '0' : '') + s;\\n\\\n    }).join('');\\n\\\n  }\\n\\\n  var Webview = (function() {\\n\\\n    var _promises = {};\\n\\\n    function Webview_() {}\\n\\\n    Webview_.prototype.post = function(message) {\\n\\\n      return (\" +\n              post_fn + \")(message);\\n\\\n    };\\n\\\n    Webview_.prototype.call = function(method) {\\n\\\n      var _id = generateId();\\n\\\n      var _params = Array.prototype.slice.call(arguments, 1);\\n\\\n      var promise = new Promise(function(resolve, reject) {\\n\\\n        _promises[_id] = { resolve, reject };\\n\\\n      });\\n\\\n      this.post(JSON.stringify({\\n\\\n        id: _id,\\n\\\n        method: method,\\n\\\n        params: _params\\n\\\n      }));\\n\\\n      return promise;\\n\\\n    };\\n\\\n    Webview_.prototype.onReply = function(id, status, result) {\\n\\\n      var promise = _promises[id];\\n\\\n      if (result !== undefined) {\\n\\\n        try {\\n\\\n          result = JSON.parse(result);\\n\\\n        } catch (e) {\\n\\\n          promise.reject(new Error(\\\"Failed to parse binding result as JSON\\\"));\\n\\\n          return;\\n\\\n        }\\n\\\n      }\\n\\\n      if (status === 0) {\\n\\\n        promise.resolve(result);\\n\\\n      } else {\\n\\\n        promise.reject(result);\\n\\\n      }\\n\\\n    };\\n\\\n    Webview_.prototype.onBind = function(name) {\\n\\\n      if (window.hasOwnProperty(name)) {\\n\\\n        throw new Error('Property \\\"' + name + '\\\" already exists');\\n\\\n      }\\n\\\n      window[name] = (function() {\\n\\\n        var params = [name].concat(Array.prototype.slice.call(arguments));\\n\\\n        return Webview_.prototype.call.apply(this, params);\\n\\\n      }).bind(this);\\n\\\n    };\\n\\\n    Webview_.prototype.onUnbind = function(name) {\\n\\\n      if (!window.hasOwnProperty(name)) {\\n\\\n        throw new Error('Property \\\"' + name + '\\\" does not exist');\\n\\\n      }\\n\\\n      delete window[name];\\n\\\n    };\\n\\\n    return Webview_;\\n\\\n  })();\\n\\\n  window.__webview__ = new Webview();\\n\\\n})()\";\n    return js;\n  }\n\n  std::string create_bind_script() {\n    std::string js_names = \"[\";\n    bool first = true;\n    for (const auto &binding : bindings) {\n      if (first) {\n        first = false;\n      } else {\n        js_names += \",\";\n      }\n      js_names += json_escape(binding.first);\n    }\n    js_names += \"]\";\n\n    auto js = std::string{} + \"(function() {\\n\\\n  'use strict';\\n\\\n  var methods = \" +\n              js_names + \";\\n\\\n  methods.forEach(function(name) {\\n\\\n    window.__webview__.onBind(name);\\n\\\n  });\\n\\\n})()\";\n    return js;\n  }\n\n  virtual void on_message(const std::string &msg) {\n    auto id = json_parse(msg, \"id\", 0);\n    auto name = json_parse(msg, \"method\", 0);\n    auto args = json_parse(msg, \"params\", 0);\n    auto found = bindings.find(name);\n    if (found == bindings.end()) {\n      return;\n    }\n    const auto &context = found->second;\n    dispatch([=] { context.call(id, args); });\n  }\n\n  virtual void on_window_created() { inc_window_count(); }\n\n  virtual void on_window_destroyed(bool skip_termination = false) {\n    if (dec_window_count() <= 0) {\n      if (!skip_termination) {\n        terminate();\n      }\n    }\n  }\n\n  // Runs the event loop until the currently queued events have been processed.\n  void deplete_run_loop_event_queue() {\n    bool done{};\n    dispatch([&] { done = true; });\n    run_event_loop_while([&] { return !done; });\n  }\n\n  // Runs the event loop while the passed-in function returns true.\n  virtual void run_event_loop_while(std::function<bool()> fn) = 0;\n\n  void dispatch_size_default() {\n    if (!owns_window() || !m_is_init_script_added) {\n      return;\n    };\n    dispatch([this]() {\n      if (!m_is_size_set) {\n        set_size(m_initial_width, m_initial_height, WEBVIEW_HINT_NONE);\n      }\n    });\n  }\n\n  void set_default_size_guard(bool guarded) { m_is_size_set = guarded; }\n\n  bool owns_window() const { return m_owns_window; }\n\nprivate:\n  static std::atomic_uint &window_ref_count() {\n    static std::atomic_uint ref_count{0};\n    return ref_count;\n  }\n\n  static unsigned int inc_window_count() { return ++window_ref_count(); }\n\n  static unsigned int dec_window_count() {\n    auto &count = window_ref_count();\n    if (count > 0) {\n      return --count;\n    }\n    return 0;\n  }\n\n  std::map<std::string, binding_ctx_t> bindings;\n  user_script *m_bind_script{};\n  std::list<user_script> m_user_scripts;\n\n  bool m_is_init_script_added{};\n  bool m_is_size_set{};\n  bool m_owns_window{};\n  static const int m_initial_width = 640;\n  static const int m_initial_height = 480;\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_ENGINE_BASE_HH\n"
  },
  {
    "path": "core/include/webview/detail/exceptions.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_EXCEPTIONS_HH\n#define WEBVIEW_DETAIL_EXCEPTIONS_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include <exception>\n\nnamespace webview {\nnamespace detail {\n\nclass bad_access : public std::exception {};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_EXCEPTIONS_HH\n"
  },
  {
    "path": "core/include/webview/detail/json.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_JSON_HH\n#define WEBVIEW_DETAIL_JSON_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include <cassert>\n#include <cstring>\n#include <string>\n\nnamespace webview {\nnamespace detail {\n\ninline int json_parse_c(const char *s, size_t sz, const char *key, size_t keysz,\n                        const char **value, size_t *valuesz) {\n  enum {\n    JSON_STATE_VALUE,\n    JSON_STATE_LITERAL,\n    JSON_STATE_STRING,\n    JSON_STATE_ESCAPE,\n    JSON_STATE_UTF8\n  } state = JSON_STATE_VALUE;\n  const char *k = nullptr;\n  int index = 1;\n  int depth = 0;\n  int utf8_bytes = 0;\n\n  *value = nullptr;\n  *valuesz = 0;\n\n  if (key == nullptr) {\n    index = static_cast<decltype(index)>(keysz);\n    if (index < 0) {\n      return -1;\n    }\n    keysz = 0;\n  }\n\n  for (; sz > 0; s++, sz--) {\n    enum {\n      JSON_ACTION_NONE,\n      JSON_ACTION_START,\n      JSON_ACTION_END,\n      JSON_ACTION_START_STRUCT,\n      JSON_ACTION_END_STRUCT\n    } action = JSON_ACTION_NONE;\n    auto c = static_cast<unsigned char>(*s);\n    switch (state) {\n    case JSON_STATE_VALUE:\n      if (c == ' ' || c == '\\t' || c == '\\n' || c == '\\r' || c == ',' ||\n          c == ':') {\n        continue;\n      } else if (c == '\"') {\n        action = JSON_ACTION_START;\n        state = JSON_STATE_STRING;\n      } else if (c == '{' || c == '[') {\n        action = JSON_ACTION_START_STRUCT;\n      } else if (c == '}' || c == ']') {\n        action = JSON_ACTION_END_STRUCT;\n      } else if (c == 't' || c == 'f' || c == 'n' || c == '-' ||\n                 (c >= '0' && c <= '9')) {\n        action = JSON_ACTION_START;\n        state = JSON_STATE_LITERAL;\n      } else {\n        return -1;\n      }\n      break;\n    case JSON_STATE_LITERAL:\n      if (c == ' ' || c == '\\t' || c == '\\n' || c == '\\r' || c == ',' ||\n          c == ']' || c == '}' || c == ':') {\n        state = JSON_STATE_VALUE;\n        s--;\n        sz++;\n        action = JSON_ACTION_END;\n      } else if (c < 32 || c > 126) {\n        return -1;\n      } // fallthrough\n    case JSON_STATE_STRING:\n      if (c < 32 || (c > 126 && c < 192)) {\n        return -1;\n      } else if (c == '\"') {\n        action = JSON_ACTION_END;\n        state = JSON_STATE_VALUE;\n      } else if (c == '\\\\') {\n        state = JSON_STATE_ESCAPE;\n      } else if (c >= 192 && c < 224) {\n        utf8_bytes = 1;\n        state = JSON_STATE_UTF8;\n      } else if (c >= 224 && c < 240) {\n        utf8_bytes = 2;\n        state = JSON_STATE_UTF8;\n      } else if (c >= 240 && c < 247) {\n        utf8_bytes = 3;\n        state = JSON_STATE_UTF8;\n      } else if (c >= 128 && c < 192) {\n        return -1;\n      }\n      break;\n    case JSON_STATE_ESCAPE:\n      if (c == '\"' || c == '\\\\' || c == '/' || c == 'b' || c == 'f' ||\n          c == 'n' || c == 'r' || c == 't' || c == 'u') {\n        state = JSON_STATE_STRING;\n      } else {\n        return -1;\n      }\n      break;\n    case JSON_STATE_UTF8:\n      if (c < 128 || c > 191) {\n        return -1;\n      }\n      utf8_bytes--;\n      if (utf8_bytes == 0) {\n        state = JSON_STATE_STRING;\n      }\n      break;\n    default:\n      return -1;\n    }\n\n    if (action == JSON_ACTION_END_STRUCT) {\n      depth--;\n    }\n\n    if (depth == 1) {\n      if (action == JSON_ACTION_START || action == JSON_ACTION_START_STRUCT) {\n        if (index == 0) {\n          *value = s;\n        } else if (keysz > 0 && index == 1) {\n          k = s;\n        } else {\n          index--;\n        }\n      } else if (action == JSON_ACTION_END ||\n                 action == JSON_ACTION_END_STRUCT) {\n        if (*value != nullptr && index == 0) {\n          *valuesz = static_cast<size_t>(s + 1 - *value);\n          return 0;\n        } else if (keysz > 0 && k != nullptr) {\n          if (keysz == static_cast<size_t>(s - k - 1) &&\n              memcmp(key, k + 1, keysz) == 0) {\n            index = 0;\n          } else {\n            index = 2;\n          }\n          k = nullptr;\n        }\n      }\n    }\n\n    if (action == JSON_ACTION_START_STRUCT) {\n      depth++;\n    }\n  }\n  return -1;\n}\n\nconstexpr bool is_json_special_char(char c) {\n  return c == '\"' || c == '\\\\' || c == '\\b' || c == '\\f' || c == '\\n' ||\n         c == '\\r' || c == '\\t';\n}\n\nconstexpr bool is_ascii_control_char(char c) {\n  // `char` may be unsigned on some targets (e.g. ARM64).\n  return static_cast<unsigned char>(c) <= 0x1f;\n}\n\ninline std::string json_escape(const std::string &s, bool add_quotes = true) {\n  // Calculate the size of the resulting string.\n  // Add space for the double quotes.\n  size_t required_length = add_quotes ? 2 : 0;\n  for (auto c : s) {\n    if (is_json_special_char(c)) {\n      // '\\' and a single following character\n      required_length += 2;\n      continue;\n    }\n    if (is_ascii_control_char(c)) {\n      // '\\', 'u', 4 digits\n      required_length += 6;\n      continue;\n    }\n    ++required_length;\n  }\n  // Allocate memory for resulting string only once.\n  std::string result;\n  result.reserve(required_length);\n  if (add_quotes) {\n    result += '\"';\n  }\n  // Copy string while escaping characters.\n  for (auto c : s) {\n    if (is_json_special_char(c)) {\n      static constexpr char special_escape_table[256] =\n          \"\\0\\0\\0\\0\\0\\0\\0\\0btn\\0fr\\0\\0\"\n          \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n          \"\\0\\0\\\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n          \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n          \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n          \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\\\\";\n      result += '\\\\';\n      // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)\n      result += special_escape_table[static_cast<unsigned char>(c)];\n      continue;\n    }\n    if (is_ascii_control_char(c)) {\n      // Escape as \\u00xx\n      static constexpr char hex_alphabet[]{\"0123456789abcdef\"};\n      auto uc = static_cast<unsigned char>(c);\n      auto h = (uc >> 4) & 0x0f;\n      auto l = uc & 0x0f;\n      result += \"\\\\u00\";\n      // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index)\n      result += hex_alphabet[h];\n      result += hex_alphabet[l];\n      // NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index)\n      continue;\n    }\n    result += c;\n  }\n  if (add_quotes) {\n    result += '\"';\n  }\n  // Should have calculated the exact amount of memory needed\n  assert(required_length == result.size());\n  return result;\n}\n\ninline int json_unescape(const char *s, size_t n, char *out) {\n  int r = 0;\n  if (*s++ != '\"') {\n    return -1;\n  }\n  while (n > 2) {\n    char c = *s;\n    if (c == '\\\\') {\n      s++;\n      n--;\n      switch (*s) {\n      case 'b':\n        c = '\\b';\n        break;\n      case 'f':\n        c = '\\f';\n        break;\n      case 'n':\n        c = '\\n';\n        break;\n      case 'r':\n        c = '\\r';\n        break;\n      case 't':\n        c = '\\t';\n        break;\n      case '\\\\':\n        c = '\\\\';\n        break;\n      case '/':\n        c = '/';\n        break;\n      case '\\\"':\n        c = '\\\"';\n        break;\n      default: // TODO: support unicode decoding\n        return -1;\n      }\n    }\n    if (out != nullptr) {\n      *out++ = c;\n    }\n    s++;\n    n--;\n    r++;\n  }\n  if (*s != '\"') {\n    return -1;\n  }\n  if (out != nullptr) {\n    *out = '\\0';\n  }\n  return r;\n}\n\ninline std::string json_parse(const std::string &s, const std::string &key,\n                              const int index) {\n  const char *value;\n  size_t value_sz;\n  if (key.empty()) {\n    json_parse_c(s.c_str(), s.length(), nullptr, index, &value, &value_sz);\n  } else {\n    json_parse_c(s.c_str(), s.length(), key.c_str(), key.length(), &value,\n                 &value_sz);\n  }\n  if (value != nullptr) {\n    if (value[0] != '\"') {\n      return {value, value_sz};\n    }\n    int n = json_unescape(value, value_sz, nullptr);\n    if (n > 0) {\n      char *decoded = new char[n + 1];\n      json_unescape(value, value_sz, decoded);\n      std::string result(decoded, n);\n      delete[] decoded;\n      return result;\n    }\n  }\n  return \"\";\n}\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_JSON_HH\n"
  },
  {
    "path": "core/include/webview/detail/native_library.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_NATIVE_LIBRARY_HH\n#define WEBVIEW_DETAIL_NATIVE_LIBRARY_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"utility/string.hh\"\n\n#include <string>\n\n#if defined(_WIN32)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#include <windows.h>\n#else\n#include <dlfcn.h>\n#endif\n\nnamespace webview {\nnamespace detail {\n\n// Holds a symbol name and associated type for code clarity.\ntemplate <typename T> class library_symbol {\npublic:\n  using type = T;\n\n  constexpr explicit library_symbol(const char *name) : m_name(name) {}\n  constexpr const char *get_name() const { return m_name; }\n\nprivate:\n  const char *m_name;\n};\n\n// Loads a native shared library and allows one to get addresses for those\n// symbols.\nclass native_library {\npublic:\n  native_library() = default;\n\n  explicit native_library(const std::string &name)\n      : m_handle{load_library(name)} {}\n\n#ifdef _WIN32\n  explicit native_library(const std::wstring &name)\n      : m_handle{load_library(name)} {}\n#endif\n\n  ~native_library() {\n    if (m_handle) {\n#ifdef _WIN32\n      FreeLibrary(m_handle);\n#else\n      dlclose(m_handle);\n#endif\n      m_handle = nullptr;\n    }\n  }\n\n  native_library(const native_library &other) = delete;\n  native_library &operator=(const native_library &other) = delete;\n  native_library(native_library &&other) noexcept { *this = std::move(other); }\n\n  native_library &operator=(native_library &&other) noexcept {\n    if (this == &other) {\n      return *this;\n    }\n    m_handle = other.m_handle;\n    other.m_handle = nullptr;\n    return *this;\n  }\n\n  // Returns true if the library is currently loaded; otherwise false.\n  operator bool() const { return is_loaded(); }\n\n  // Get the address for the specified symbol or nullptr if not found.\n  template <typename Symbol>\n  typename Symbol::type get(const Symbol &symbol) const {\n    if (is_loaded()) {\n      // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)\n#ifdef _WIN32\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wcast-function-type\"\n#endif\n      return reinterpret_cast<typename Symbol::type>(\n          GetProcAddress(m_handle, symbol.get_name()));\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n#else\n      return reinterpret_cast<typename Symbol::type>(\n          dlsym(m_handle, symbol.get_name()));\n#endif\n      // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)\n    }\n    return nullptr;\n  }\n\n  // Returns true if the library is currently loaded; otherwise false.\n  bool is_loaded() const { return !!m_handle; }\n\n  void detach() { m_handle = nullptr; }\n\n  // Returns true if the library by the given name is currently loaded; otherwise false.\n  static inline bool is_loaded(const std::string &name) {\n#ifdef _WIN32\n    auto handle = GetModuleHandleW(widen_string(name).c_str());\n#else\n    auto handle = dlopen(name.c_str(), RTLD_NOW | RTLD_NOLOAD);\n    if (handle) {\n      dlclose(handle);\n    }\n#endif\n    return !!handle;\n  }\n\nprivate:\n#ifdef _WIN32\n  using mod_handle_t = HMODULE;\n#else\n  using mod_handle_t = void *;\n#endif\n\n  static inline mod_handle_t load_library(const std::string &name) {\n#ifdef _WIN32\n    return load_library(widen_string(name));\n#else\n    return dlopen(name.c_str(), RTLD_NOW);\n#endif\n  }\n\n#ifdef _WIN32\n  static inline mod_handle_t load_library(const std::wstring &name) {\n    return LoadLibraryW(name.c_str());\n  }\n#endif\n\n  mod_handle_t m_handle{};\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_NATIVE_LIBRARY_HH\n"
  },
  {
    "path": "core/include/webview/detail/optional.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_OPTIONAL_HH\n#define WEBVIEW_DETAIL_OPTIONAL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"exceptions.hh\"\n\n#include <new>\n#include <type_traits>\n#include <utility>\n\nnamespace webview {\nnamespace detail {\n\ntemplate <typename T> class optional {\npublic:\n  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)\n  optional() = default;\n\n  optional(const T &other) noexcept : m_has_data{true} {\n    new (&m_data) T{other};\n  }\n\n  optional(T &&other) noexcept : m_has_data{true} {\n    new (&m_data) T{std::move(other)};\n  }\n\n  optional(const optional<T> &other) noexcept { *this = other; }\n\n  optional &operator=(const optional<T> &other) noexcept {\n    if (this == &other) {\n      return *this;\n    }\n    m_has_data = other.has_value();\n    if (m_has_data) {\n      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n      new (&m_data) T{*reinterpret_cast<const T *>(&other.m_data)};\n    }\n    return *this;\n  }\n\n  optional(optional<T> &&other) noexcept { *this = std::move(other); }\n\n  optional &operator=(optional<T> &&other) noexcept {\n    if (this == &other) {\n      return *this;\n    }\n    m_has_data = other.has_value();\n    if (m_has_data) {\n      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n      new (&m_data) T{std::move(*reinterpret_cast<T *>(&other.m_data))};\n    }\n    return *this;\n  }\n\n  ~optional() {\n    if (m_has_data) {\n      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n      reinterpret_cast<T *>(&m_data)->~T();\n    }\n  }\n\n  const T &get() const {\n    if (!m_has_data) {\n      throw bad_access{};\n    }\n    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n    return *reinterpret_cast<const T *>(&m_data);\n  }\n\n  T &get() {\n    if (!m_has_data) {\n      throw bad_access{};\n    }\n    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n    return *reinterpret_cast<T *>(&m_data);\n  }\n\n  bool has_value() const { return m_has_data; }\n\nprivate:\n  // NOLINTNEXTLINE(bugprone-sizeof-expression): pointer to aggregate is OK\n  typename std::aligned_storage<sizeof(T), alignof(T)>::type m_data;\n  bool m_has_data{};\n};\n\ntemplate <> class optional<void> {};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_OPTIONAL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSApplication.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSAPPLICATION_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSAPPLICATION_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSString.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nenum NSApplicationActivationPolicy : NSInteger {\n  NSApplicationActivationPolicyRegular = 0\n};\n\nenum NSEventMask : NSUInteger { NSEventMaskAny = NSUIntegerMax };\n\nenum NSModalResponse : NSInteger { NSModalResponseOK = 1 };\n\nnamespace NSRunLoopMode {\ninline id NSDefaultRunLoopMode() {\n  return NSString_stringWithUTF8String(\"kCFRunLoopDefaultMode\");\n}\n} // namespace NSRunLoopMode\n\ninline void NSApplication_set_delegate(id self, id delegate) {\n  objc::msg_send<void>(self, objc::selector(\"setDelegate:\"), delegate);\n}\n\ninline void NSApplication_run(id self) {\n  objc::msg_send<void>(self, objc::selector(\"run\"));\n}\n\ninline void NSApplication_stop(id self, id sender = nullptr) {\n  objc::msg_send<void>(self, objc::selector(\"stop:\"), sender);\n}\n\ninline id NSApplication_get_sharedApplication() {\n  return objc::msg_send<id>(objc::get_class(\"NSApplication\"),\n                            objc::selector(\"sharedApplication\"));\n}\n\ninline void NSApplication_sendEvent(id self, id event) {\n  objc::msg_send<void>(self, objc::selector(\"sendEvent:\"), event);\n}\n\ninline id NSApplication_nextEventMatchingMask(id self, NSEventMask mask,\n                                              id expiration, id mode,\n                                              bool dequeue) {\n  return objc::msg_send<id>(\n      self, objc::selector(\"nextEventMatchingMask:untilDate:inMode:dequeue:\"),\n      mask, expiration, mode, dequeue);\n}\n\ninline void\nNSApplication_setActivationPolicy(id self,\n                                  NSApplicationActivationPolicy policy) {\n  objc::msg_send<void>(self, objc::selector(\"setActivationPolicy:\"), policy);\n}\n\ninline void NSApplication_activateIgnoringOtherApps(id self, bool ignore) {\n  objc::msg_send<void>(self, objc::selector(\"activateIgnoringOtherApps:\"),\n                       static_cast<BOOL>(ignore));\n}\n\ninline void NSApplication_postEvent(id self, id event, bool at_start) {\n  objc::msg_send<void>(self, objc::selector(\"postEvent:atStart:\"), event,\n                       static_cast<BOOL>(at_start));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSAPPLICATION_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSBundle.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSBUNDLE_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSBUNDLE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSBundle_get_mainBundle() {\n  return objc::msg_send<id>(objc::get_class(\"NSBundle\"),\n                            objc::selector(\"mainBundle\"));\n}\n\ninline id NSBundle_get_bundlePath(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"bundlePath\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSBUNDLE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSEvent.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSEVENT_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSEVENT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSPoint.hh\"\n#include \"types.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nenum NSEventType : NSUInteger {\n  // For macOS 10.12+; replaces NSApplicationDefined (macOS 10.0–10.12)\n  // with the same value\n  NSEventTypeApplicationDefined = 15\n};\n\nenum NSEventModifierFlags : NSUInteger {};\n\ninline id NSEvent_otherEventWithType(NSEventType type, NSPoint location,\n                                     NSEventModifierFlags modifier_flags,\n                                     NSTimeInterval timestamp,\n                                     NSInteger window_number, id context,\n                                     short subtype, NSInteger data1,\n                                     NSInteger data2) {\n  return objc::msg_send<id>(\n      objc::get_class(\"NSEvent\"),\n      objc::selector(\"otherEventWithType:location:modifierFlags:timestamp:\"\n                     \"windowNumber:context:subtype:data1:data2:\"),\n      type, location, modifier_flags, timestamp, window_number, context,\n      subtype, data1, data2);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSEVENT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSInvocation.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSINVOCATION_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSINVOCATION_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSInvocation_invocationWithMethodSignature(id sig) {\n  return objc::msg_send<id>(objc::get_class(\"NSInvocation\"),\n                            objc::selector(\"invocationWithMethodSignature:\"),\n                            sig);\n}\n\ninline void NSInvocation_set_target(id self, id target) {\n  objc::msg_send<void>(self, objc::selector(\"setTarget:\"), target);\n}\n\ninline void NSInvocation_setArgument(id self, void *location, NSInteger index) {\n  objc::msg_send<void>(self, objc::selector(\"setArgument:atIndex:\"), location,\n                       index);\n}\n\ninline void NSInvocation_invoke(id self) {\n  objc::msg_send<void>(self, objc::selector(\"invoke\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSInvocation_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSMethodSignature.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSMETHODSIGNATURE_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSMETHODSIGNATURE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSMethodSignature_signatureWithObjCTypes(const char *types) {\n  return objc::msg_send<id>(objc::get_class(\"NSMethodSignature\"),\n                            objc::selector(\"signatureWithObjCTypes:\"), types);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSMETHODSIGNATURE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSNotification.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSNOTIFICATION_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSNOTIFICATION_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSNotification_get_object(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"object\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSNOTIFICATION_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSNumber.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSNUMBER_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSNUMBER_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSNumber_numberWithBool(bool value) {\n  return objc::msg_send<id>(objc::get_class(\"NSNumber\"),\n                            objc::selector(\"numberWithBool:\"),\n                            static_cast<BOOL>(value));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSNUMBER_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSObject.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSOBJECT_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSOBJECT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline void NSObject_setValue_forKey(id self, id value, id key) {\n  objc::msg_send<void>(self, objc::selector(\"setValue:forKey:\"), value, key);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSOBJECT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSOpenPanel.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSOPENPANEL_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSOPENPANEL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSOpenPanel_openPanel() {\n  return objc::msg_send<id>(objc::get_class(\"NSOpenPanel\"),\n                            objc::selector(\"openPanel\"));\n}\n\ninline void NSOpenPanel_set_canChooseFiles(id self, bool value) {\n  objc::msg_send<void>(self, objc::selector(\"setCanChooseFiles:\"),\n                       static_cast<BOOL>(value));\n}\n\ninline void NSOpenPanel_set_canChooseDirectories(id self, bool value) {\n  objc::msg_send<void>(self, objc::selector(\"setCanChooseDirectories:\"),\n                       static_cast<BOOL>(value));\n}\n\ninline void NSOpenPanel_set_allowsMultipleSelection(id self, bool value) {\n  objc::msg_send<void>(self, objc::selector(\"setAllowsMultipleSelection:\"),\n                       static_cast<BOOL>(value));\n}\n\ninline id NSOpenPanel_get_URLs(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"URLs\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSOPENPANEL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSPoint.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSPOINT_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSPOINT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include <CoreGraphics/CoreGraphics.h>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nusing NSPoint = CGPoint;\n\nconstexpr inline NSPoint NSPointMake(CGFloat x, CGFloat y) {\n  return CGPointMake(x, y);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSPOINT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSRect.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSRECT_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSRECT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include <CoreGraphics/CoreGraphics.h>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nusing NSRect = CGRect;\n\nconstexpr inline NSRect NSRectMake(CGFloat x, CGFloat y, CGFloat w, CGFloat h) {\n  return CGRectMake(x, y, w, h);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSRECT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSSavePanel.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSSAVEPANEL_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSSAVEPANEL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSApplication.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline NSModalResponse NSSavePanel_runModal(id self) {\n  return objc::msg_send<NSModalResponse>(self, objc::selector(\"runModal\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSSAVEPANEL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSSize.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSSIZE_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSSIZE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include <CoreGraphics/CoreGraphics.h>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nusing NSSize = CGSize;\n\nconstexpr inline NSSize NSSizeMake(CGFloat w, CGFloat h) {\n  return CGSizeMake(w, h);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSSIZE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSString.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSSTRING_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSSTRING_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\n#include <string>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nenum NSStringEncoding : NSUInteger {\n  NSASCIIStringEncoding = 1,\n  NSUTF8StringEncoding = 4\n};\n\ninline bool NSString_hasSuffix(id self, id suffix) {\n  return static_cast<bool>(\n      objc::msg_send<BOOL>(self, objc::selector(\"hasSuffix:\"), suffix));\n}\n\ninline id NSString_alloc() {\n  return objc::msg_send<id>(objc::get_class(\"NSString\"),\n                            objc::selector(\"alloc\"));\n}\n\ninline id NSString_initWithBytes(id self, const void *bytes, NSUInteger length,\n                                 NSStringEncoding encoding) {\n  return objc::msg_send<id>(self,\n                            objc::selector(\"initWithBytes:length:encoding:\"),\n                            bytes, length, encoding);\n}\n\ninline id NSString_stringWithUTF8String(const char *utf8_string) {\n  return objc::msg_send<id>(objc::get_class(\"NSString\"),\n                            objc::selector(\"stringWithUTF8String:\"),\n                            utf8_string);\n}\n\ninline id NSString_stringWithUTF8String(const std::string &utf8_string) {\n  return objc::autorelease(NSString_initWithBytes(\n      NSString_alloc(), utf8_string.data(),\n      static_cast<NSUInteger>(utf8_string.size()), NSUTF8StringEncoding));\n}\n\ninline const char *NSString_get_UTF8String(id self) {\n  return objc::msg_send<const char *>(self, objc::selector(\"UTF8String\"));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSSTRING_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSURL.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSURL_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSURL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSString.hh\"\n\n#include <string>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSURL_URLWithString(id string) {\n  return objc::msg_send<id>(objc::get_class(\"NSURL\"),\n                            objc::selector(\"URLWithString:\"), string);\n}\n\ninline id NSURL_URLWithString(const char *string) {\n  return NSURL_URLWithString(NSString_stringWithUTF8String(string));\n}\n\ninline id NSURL_URLWithString(const std::string &string) {\n  return NSURL_URLWithString(NSString_stringWithUTF8String(string));\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSURL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSURLRequest.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSURLREQUEST_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSURLREQUEST_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSURLRequest_requestWithURL(id url) {\n  return objc::msg_send<id>(objc::get_class(\"NSURLRequest\"),\n                            objc::selector(\"requestWithURL:\"), url);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSURLREQUEST_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSValue.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSVALUE_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSVALUE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\ninline id NSValue_valueWithPointer(const void *pointer) {\n  return objc::msg_send<id>(objc::get_class(\"NSValue\"),\n                            objc::selector(\"valueWithPointer:\"), pointer);\n}\n\ninline void NSValue_getValue(id self, void *value, NSUInteger size) {\n  objc::msg_send<void>(self, objc::selector(\"getValue:size:\"), value, size);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSVALUE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSView.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSVIEW_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSVIEW_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSRect.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nenum NSAutoresizingMaskOptions : NSUInteger {\n  NSViewMinXMargin = 1,\n  NSViewWidthSizable = 2,\n  NSViewMaxXMargin = 4,\n  NSViewMinYMargin = 8,\n  NSViewHeightSizable = 16,\n  NSViewMaxYMargin = 32\n};\n\ninline id NSView_alloc() {\n  return objc::msg_send<id>(objc::get_class(\"NSView\"), objc::selector(\"alloc\"));\n}\n\ninline id NSView_initWithFrame(id self, NSRect frame_rect) {\n  return objc::msg_send<id>(self, objc::selector(\"initWithFrame:\"), frame_rect);\n}\n\ninline id NSView_withFrame(NSRect frame_rect) {\n  return objc::autorelease(NSView_initWithFrame(NSView_alloc(), frame_rect));\n}\n\ninline void NSView_set_autoresizesSubviews(id self, bool resizes) {\n  objc::msg_send<void>(self, objc::selector(\"setAutoresizesSubviews:\"),\n                       static_cast<BOOL>(resizes));\n}\n\ninline void NSView_addSubview(id self, id subview) {\n  objc::msg_send<void>(self, objc::selector(\"addSubview:\"), subview);\n}\n\ninline NSRect NSView_get_bounds(id self) {\n  return objc::msg_send_stret<NSRect>(self, objc::selector(\"bounds\"));\n}\n\ninline void NSView_set_frame(id self, NSRect frame) {\n  objc::msg_send<void>(self, objc::selector(\"setFrame:\"), frame);\n}\n\ninline void NSView_set_autoresizingMask(id self,\n                                        NSAutoresizingMaskOptions mask) {\n  objc::msg_send<void>(self, objc::selector(\"setAutoresizingMask:\"), mask);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSVIEW_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/NSWindow.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_NSWINDOW_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_NSWINDOW_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n#include \"NSRect.hh\"\n#include \"NSSize.hh\"\n\n#include <string>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nenum NSBackingStoreType : NSUInteger { NSBackingStoreBuffered = 2 };\n\nenum NSWindowStyleMask : NSUInteger {\n  NSWindowStyleMaskTitled = 1,\n  NSWindowStyleMaskClosable = 2,\n  NSWindowStyleMaskMiniaturizable = 4,\n  NSWindowStyleMaskResizable = 8\n};\n\ninline id NSWindow_alloc() {\n  return objc::msg_send<id>(objc::get_class(\"NSWindow\"),\n                            objc::selector(\"alloc\"));\n}\n\ninline id NSWindow_initWithContentRect(id self, NSRect content_rect,\n                                       NSWindowStyleMask style,\n                                       NSBackingStoreType backing_store_type,\n                                       bool defer) {\n  return objc::msg_send<id>(\n      self, objc::selector(\"initWithContentRect:styleMask:backing:defer:\"),\n      content_rect, style, backing_store_type, static_cast<BOOL>(defer));\n}\n\ninline id NSWindow_withContentRect(NSRect content_rect, NSWindowStyleMask style,\n                                   NSBackingStoreType backing_store_type,\n                                   bool defer) {\n  return objc::autorelease(NSWindow_initWithContentRect(\n      NSWindow_alloc(), content_rect, style, backing_store_type, defer));\n}\n\ninline void NSWindow_close(id self) {\n  objc::msg_send<void>(self, objc::selector(\"close\"));\n}\n\ninline NSRect NSWindow_get_frame(id self) {\n  return objc::msg_send_stret<NSRect>(self, objc::selector(\"frame\"));\n}\n\ninline void NSWindow_setFrame(id self, NSRect frame_rect, bool display,\n                              bool animate) {\n  objc::msg_send<void>(self, objc::selector(\"setFrame:display:animate:\"),\n                       frame_rect, static_cast<BOOL>(display),\n                       static_cast<BOOL>(animate));\n}\n\ninline void NSWindow_set_styleMask(id self, NSWindowStyleMask style) {\n  objc::msg_send<void>(self, objc::selector(\"setStyleMask:\"), style);\n}\n\ninline void NSWindow_set_title(id self, const std::string &title) {\n  objc::autoreleasepool arp;\n  objc::msg_send<void>(\n      self, objc::selector(\"setTitle:\"),\n      objc::msg_send<id>(objc::get_class(\"NSString\"),\n                         objc::selector(\"stringWithUTF8String:\"),\n                         title.c_str()));\n}\n\ninline void NSWindow_makeKeyAndOrderFront(id self, id sender = nullptr) {\n  objc::msg_send<void>(self, objc::selector(\"makeKeyAndOrderFront:\"), sender);\n}\n\ninline void NSWindow_set_contentView(id self, id view) {\n  objc::msg_send<void>(self, objc::selector(\"setContentView:\"), view);\n}\n\ninline id NSWindow_get_contentView(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"contentView\"));\n}\n\ninline void NSWindow_set_delegate(id self, id delegate) {\n  objc::msg_send<void>(self, objc::selector(\"setDelegate:\"), delegate);\n}\n\ninline void NSWindow_center(id self) {\n  objc::msg_send<void>(self, objc::selector(\"center\"));\n}\n\ninline void NSWindow_set_contentMinSize(id self, NSSize size) {\n  objc::msg_send<void>(self, objc::selector(\"setContentMinSize:\"), size);\n}\n\ninline void NSWindow_set_contentMaxSize(id self, NSSize size) {\n  objc::msg_send<void>(self, objc::selector(\"setContentMaxSize:\"), size);\n}\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSWINDOW_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/cocoa.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_COCOA_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_COCOA_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n// IWYU pragma: begin_exports\n#include \"NSApplication.hh\"\n#include \"NSBundle.hh\"\n#include \"NSEvent.hh\"\n#include \"NSInvocation.hh\"\n#include \"NSMethodSignature.hh\"\n#include \"NSNotification.hh\"\n#include \"NSNumber.hh\"\n#include \"NSObject.hh\"\n#include \"NSOpenPanel.hh\"\n#include \"NSPoint.hh\"\n#include \"NSRect.hh\"\n#include \"NSSavePanel.hh\"\n#include \"NSSize.hh\"\n#include \"NSString.hh\"\n#include \"NSURL.hh\"\n#include \"NSURLRequest.hh\"\n#include \"NSValue.hh\"\n#include \"NSView.hh\"\n#include \"NSWindow.hh\"\n// IWYU pragma: end_exports\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_COCOA_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/cocoa/types.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_COCOA_TYPES_HH\n#define WEBVIEW_PLATFORM_DARWIN_COCOA_TYPES_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include <objc/NSObjCRuntime.h>\n\nnamespace webview {\nnamespace detail {\nnamespace cocoa {\n\nusing NSTimeInterval = double;\n\n} // namespace cocoa\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_TYPES_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/objc/Class.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_OBJC_CLASS_HH\n#define WEBVIEW_PLATFORM_DARWIN_OBJC_CLASS_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n\n#include \"invoke.hh\"\n\n#include <objc/objc-runtime.h>\n\nnamespace webview {\nnamespace detail {\nnamespace objc {\n\ninline id Class_new(Class class_) {\n  return msg_send<id>(class_, selector(\"new\"));\n}\n\ninline Class get_class(const char *name) { return objc_getClass(name); }\n\n} // namespace objc\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_OBJC_CLASS_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/objc/autoreleasepool.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_OBJC_AUTORELEASEPOOL_HH\n#define WEBVIEW_PLATFORM_DARWIN_OBJC_AUTORELEASEPOOL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n\n#include \"invoke.hh\"\n\n#include <objc/objc-runtime.h>\n\nnamespace webview {\nnamespace detail {\nnamespace objc {\n\n// Wrapper around NSAutoreleasePool that drains the pool on destruction.\nclass autoreleasepool {\npublic:\n  autoreleasepool()\n      : m_pool(msg_send<id>(get_class(\"NSAutoreleasePool\"), selector(\"new\"))) {}\n\n  ~autoreleasepool() {\n    if (m_pool) {\n      msg_send<void>(m_pool, selector(\"drain\"));\n    }\n  }\n\n  autoreleasepool(const autoreleasepool &) = delete;\n  autoreleasepool &operator=(const autoreleasepool &) = delete;\n  autoreleasepool(autoreleasepool &&) = delete;\n  autoreleasepool &operator=(autoreleasepool &&) = delete;\n\nprivate:\n  id m_pool{};\n};\n\n} // namespace objc\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_OBJC_AUTORELEASEPOOL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/objc/invoke.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_OBJC_INVOKE_HH\n#define WEBVIEW_PLATFORM_DARWIN_OBJC_INVOKE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n\n#include <objc/objc-runtime.h>\n\nnamespace webview {\nnamespace detail {\nnamespace objc {\n\n// A convenient template function for unconditionally casting the specified\n// C-like function into a function that can be called with the given return\n// type and arguments. Caller takes full responsibility for ensuring that\n// the function call is valid. It is assumed that the function will not\n// throw exceptions.\ntemplate <typename Result, typename Callable, typename... Args>\nResult invoke(Callable callable, Args... args) noexcept {\n  return reinterpret_cast<Result (*)(Args...)>(callable)(args...);\n}\n\n// Calls objc_msgSend.\ntemplate <typename Result, typename... Args>\nResult msg_send(Args... args) noexcept {\n  return invoke<Result>(objc_msgSend, args...);\n}\n\n// Calls objc_msgSend_stret or objc_msgSend depending on architecture.\ntemplate <typename Result, typename... Args>\nResult msg_send_stret(Args... args) noexcept {\n#if defined(__arm64__)\n  return invoke<Result>(objc_msgSend, args...);\n#else\n  return invoke<Result>(objc_msgSend_stret, args...);\n#endif\n}\n\ninline SEL selector(const char *name) { return sel_registerName(name); }\n\n} // namespace objc\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_OBJC_INVOKE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/objc/memory.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_OBJC_MEMORY_HH\n#define WEBVIEW_PLATFORM_DARWIN_OBJC_MEMORY_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n\n#include \"invoke.hh\"\n\n#include <objc/objc-runtime.h>\n\nnamespace webview {\nnamespace detail {\nnamespace objc {\n\ninline id autorelease(id object) {\n  return msg_send<id>(object, selector(\"autorelease\"));\n}\n\ninline id retain(id object) { return msg_send<id>(object, selector(\"retain\")); }\n\ninline void release(id object) { msg_send<void>(object, selector(\"release\")); }\n\n} // namespace objc\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_OBJC_MEMORY_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/objc/objc.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_OBJC_OBJC_HH\n#define WEBVIEW_PLATFORM_DARWIN_OBJC_OBJC_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n\n// IWYU pragma: begin_exports\n#include \"Class.hh\"\n#include \"autoreleasepool.hh\"\n#include \"invoke.hh\"\n#include \"memory.hh\"\n// IWYU pragma: end_exports\n\n#include <objc/NSObjCRuntime.h>\n#include <objc/objc-runtime.h>\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_OBJC_OBJC_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKOpenPanelParameters.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKOPENPANELPARAMETERS_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKOPENPANELPARAMETERS_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\ninline bool WKOpenPanelParameters_get_allowsMultipleSelection(id self) {\n  return static_cast<bool>(\n      objc::msg_send<BOOL>(self, objc::selector(\"allowsMultipleSelection\")));\n}\n\ninline bool WKOpenPanelParameters_get_allowsDirectories(id self) {\n  return static_cast<bool>(\n      objc::msg_send<BOOL>(self, objc::selector(\"allowsDirectories\")));\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKOPENPANELPARAMETERS_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKScriptMessage.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKSCRIPTMESSAGE_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKSCRIPTMESSAGE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\ninline id WKScriptMessage_get_body(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"body\"));\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKSCRIPTMESSAGE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKUserContentController.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERCONTENTCONTROLLER_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERCONTENTCONTROLLER_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\ninline void WKUserContentController_addScriptMessageHandler(id self, id handler,\n                                                            id name) {\n  objc::msg_send<void>(self, objc::selector(\"addScriptMessageHandler:name:\"),\n                       handler, name);\n}\n\ninline void WKUserContentController_addUserScript(id self, id user_script) {\n  objc::msg_send<void>(self, objc::selector(\"addUserScript:\"), user_script);\n}\n\ninline void WKUserContentController_removeAllUserScripts(id self) {\n  objc::msg_send<id>(self, objc::selector(\"removeAllUserScripts\"));\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERCONTENTCONTROLLER_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKUserScript.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERSCRIPT_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERSCRIPT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\nenum WKUserScriptInjectionTime : NSInteger {\n  WKUserScriptInjectionTimeAtDocumentStart = 0\n};\n\ninline id WKUserScript_alloc() {\n  return objc::msg_send<id>(objc::get_class(\"WKUserScript\"),\n                            objc::selector(\"alloc\"));\n}\n\ninline id WKUserScript_initWithSource(id self, id source,\n                                      WKUserScriptInjectionTime injection_time,\n                                      bool for_main_frame_only) {\n  return objc::msg_send<id>(\n      self, objc::selector(\"initWithSource:injectionTime:forMainFrameOnly:\"),\n      source, injection_time, static_cast<BOOL>(for_main_frame_only));\n}\n\ninline id WKUserScript_withSource(id source,\n                                  WKUserScriptInjectionTime injection_time,\n                                  bool for_main_frame_only) {\n  return objc::autorelease(WKUserScript_initWithSource(\n      WKUserScript_alloc(), source, injection_time, for_main_frame_only));\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKUSERSCRIPT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKWebView.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEW_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEW_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\n#include <CoreGraphics/CoreGraphics.h>\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\ninline id WKWebView_alloc() {\n  return objc::msg_send<id>(objc::get_class(\"WKWebView\"),\n                            objc::selector(\"alloc\"));\n}\n\ninline id WKWebView_initWithFrame(id self, CGRect frame, id configuration) {\n  return objc::msg_send<id>(self,\n                            objc::selector(\"initWithFrame:configuration:\"),\n                            frame, configuration);\n}\n\ninline id WKWebView_withFrame(CGRect frame, id configuration) {\n  return objc::autorelease(\n      WKWebView_initWithFrame(WKWebView_alloc(), frame, configuration));\n}\n\ninline id WKWebView_get_UIDelegate(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"UIDelegate\"));\n}\n\ninline void WKWebView_set_UIDelegate(id self, id ui_delegate) {\n  objc::msg_send<void>(self, objc::selector(\"setUIDelegate:\"), ui_delegate);\n}\n\ninline id WKWebView_loadHTMLString(id self, id string, id base_url) {\n  return objc::msg_send<id>(self, objc::selector(\"loadHTMLString:baseURL:\"),\n                            string, base_url);\n}\n\ninline id WKWebView_get_URL(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"URL\"));\n}\n\ninline id WKWebView_loadRequest(id self, id request) {\n  return objc::msg_send<id>(self, objc::selector(\"loadRequest:\"), request);\n}\n\ninline void WKWebView_evaluateJavaScript(id self, id js_string,\n                                         const void *completion_handler) {\n  return objc::msg_send<void>(\n      self, objc::selector(\"evaluateJavaScript:completionHandler:\"), js_string,\n      completion_handler);\n}\n\ninline void WKWebView_set_inspectable(id self, bool inspectable) {\n#if defined(__has_builtin)\n#if __has_builtin(__builtin_available)\n  if (__builtin_available(macOS 13.3, iOS 16.4, tvOS 16.4, *)) {\n    objc::msg_send<void>(self, objc::selector(\"setInspectable:\"),\n                         static_cast<BOOL>(inspectable));\n  }\n#else\n#error __builtin_available not supported by compiler\n#endif\n#else\n#error __has_builtin not supported by compiler\n#endif\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEW_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/WKWebViewConfiguration.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEWCONFIGURATION_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEWCONFIGURATION_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n#include \"../objc/objc.hh\"\n\nnamespace webview {\nnamespace detail {\nnamespace webkit {\n\ninline id WKWebViewConfiguration_new() {\n  return objc::msg_send<id>(objc::get_class(\"WKWebViewConfiguration\"),\n                            objc::selector(\"new\"));\n}\n\ninline id WKWebViewConfiguration_get_userContentController(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"userContentController\"));\n}\n\ninline id WKWebViewConfiguration_get_preferences(id self) {\n  return objc::msg_send<id>(self, objc::selector(\"preferences\"));\n}\n\n} // namespace webkit\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_WKWEBVIEWCONFIGURATION_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/darwin/webkit/webkit.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_DARWIN_WEBKIT_HH\n#define WEBVIEW_PLATFORM_DARWIN_WEBKIT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n\n// IWYU pragma: begin_exports\n#include \"WKOpenPanelParameters.hh\"\n#include \"WKScriptMessage.hh\"\n#include \"WKUserContentController.hh\"\n#include \"WKUserScript.hh\"\n#include \"WKWebView.hh\"\n#include \"WKWebViewConfiguration.hh\"\n// IWYU pragma: end_exports\n\n#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_DARWIN_WEBKIT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/linux/gtk/compat.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_LINUX_GTK_COMPAT_HH\n#define WEBVIEW_PLATFORM_LINUX_GTK_COMPAT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n\n#include <gtk/gtk.h>\n\n#if GTK_MAJOR_VERSION >= 4\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/x11/gdkx.h>\n#endif\n\n#elif GTK_MAJOR_VERSION >= 3\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/gdkx.h>\n#endif\n\n#endif\n\nnamespace webview {\nnamespace detail {\n\n/**\n * GTK compatibility helper class.\n */\nclass gtk_compat {\npublic:\n  static gboolean init_check() {\n#if GTK_MAJOR_VERSION >= 4\n    return gtk_init_check();\n#else\n    return gtk_init_check(nullptr, nullptr);\n#endif\n  }\n\n  static GtkWidget *window_new() {\n#if GTK_MAJOR_VERSION >= 4\n    return gtk_window_new();\n#else\n    return gtk_window_new(GTK_WINDOW_TOPLEVEL);\n#endif\n  }\n\n  static void window_set_child(GtkWindow *window, GtkWidget *widget) {\n#if GTK_MAJOR_VERSION >= 4\n    gtk_window_set_child(window, widget);\n#else\n    gtk_container_add(GTK_CONTAINER(window), widget);\n#endif\n  }\n\n  static void window_remove_child(GtkWindow *window, GtkWidget *widget) {\n#if GTK_MAJOR_VERSION >= 4\n    if (gtk_window_get_child(window) == widget) {\n      gtk_window_set_child(window, nullptr);\n    }\n#else\n    gtk_container_remove(GTK_CONTAINER(window), widget);\n#endif\n  }\n\n  static void widget_set_visible(GtkWidget *widget, bool visible) {\n#if GTK_MAJOR_VERSION >= 4\n    gtk_widget_set_visible(widget, visible ? TRUE : FALSE);\n#else\n    if (visible) {\n      gtk_widget_show(widget);\n    } else {\n      gtk_widget_hide(widget);\n    }\n#endif\n  }\n\n  static void window_set_size(GtkWindow *window, int width, int height) {\n    // GTK 4 can set a default window size, but unlike GTK 3 it can't resize\n    // the window after it has been set up.\n#if GTK_MAJOR_VERSION >= 4\n    gtk_window_set_default_size(window, width, height);\n#else\n    gtk_window_resize(window, width, height);\n#endif\n  }\n\n  static void window_set_max_size(GtkWindow *window, int width, int height) {\n// X11-specific features are available in GTK 3 but not GTK 4\n#if GTK_MAJOR_VERSION < 4\n    GdkGeometry g{};\n    g.max_width = width;\n    g.max_height = height;\n    GdkWindowHints h = GDK_HINT_MAX_SIZE;\n    gtk_window_set_geometry_hints(GTK_WINDOW(window), nullptr, &g, h);\n#else\n    // Avoid \"unused parameter\" warnings\n    (void)window;\n    (void)width;\n    (void)height;\n#endif\n  }\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_LINUX_GTK_COMPAT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/linux/webkitgtk/compat.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_LINUX_WEBKITGTK_COMPAT_HH\n#define WEBVIEW_PLATFORM_LINUX_WEBKITGTK_COMPAT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n\n#include <functional>\n#include <string>\n\n#include <gtk/gtk.h>\n\n#if GTK_MAJOR_VERSION >= 4\n\n#include <jsc/jsc.h>\n#include <webkit/webkit.h>\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/x11/gdkx.h>\n#endif\n\n#elif GTK_MAJOR_VERSION >= 3\n\n#include <JavaScriptCore/JavaScript.h>\n#include <webkit2/webkit2.h>\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/gdkx.h>\n#endif\n\n#endif\n\nnamespace webview {\nnamespace detail {\n\n/**\n * WebKitGTK compatibility helper class.\n */\nclass webkitgtk_compat {\npublic:\n#if GTK_MAJOR_VERSION >= 4\n  using wk_handler_js_value_t = JSCValue;\n#else\n  using wk_handler_js_value_t = WebKitJavascriptResult;\n#endif\n\n  using on_script_message_received_t =\n      std::function<void(WebKitUserContentManager *, const std::string &)>;\n  static void\n  connect_script_message_received(WebKitUserContentManager *manager,\n                                  const std::string &handler_name,\n                                  on_script_message_received_t handler) {\n    std::string signal_name = \"script-message-received::\";\n    signal_name += handler_name;\n\n    auto callback = +[](WebKitUserContentManager *manager,\n                        wk_handler_js_value_t *r, gpointer arg) {\n      auto *handler = static_cast<on_script_message_received_t *>(arg);\n      (*handler)(manager, get_string_from_js_result(r));\n    };\n\n    auto deleter = +[](gpointer data, GClosure *) {\n      delete static_cast<on_script_message_received_t *>(data);\n    };\n\n    g_signal_connect_data(manager, signal_name.c_str(), G_CALLBACK(callback),\n                          new on_script_message_received_t{handler}, deleter,\n                          static_cast<GConnectFlags>(0) /*G_CONNECT_DEFAULT*/);\n  }\n\n  static std::string get_string_from_js_result(JSCValue *r) {\n    char *cs = jsc_value_to_string(r);\n    std::string s{cs};\n    g_free(cs);\n    return s;\n  }\n\n#if GTK_MAJOR_VERSION < 4\n  static std::string get_string_from_js_result(WebKitJavascriptResult *r) {\n#if (WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION >= 22) ||               \\\n    WEBKIT_MAJOR_VERSION > 2\n    JSCValue *value = webkit_javascript_result_get_js_value(r);\n    return get_string_from_js_result(value);\n#else\n    JSGlobalContextRef ctx = webkit_javascript_result_get_global_context(r);\n    JSValueRef value = webkit_javascript_result_get_value(r);\n    JSStringRef js = JSValueToStringCopy(ctx, value, nullptr);\n    size_t n = JSStringGetMaximumUTF8CStringSize(js);\n    char *cs = g_new(char, n);\n    JSStringGetUTF8CString(js, cs, n);\n    JSStringRelease(js);\n    std::string s{cs};\n    g_free(cs);\n    return s;\n#endif\n  }\n#endif\n\n  static void user_content_manager_register_script_message_handler(\n      WebKitUserContentManager *manager, const gchar *name) {\n#if GTK_MAJOR_VERSION >= 4\n    webkit_user_content_manager_register_script_message_handler(manager, name,\n                                                                nullptr);\n#else\n    webkit_user_content_manager_register_script_message_handler(manager, name);\n#endif\n  }\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_LINUX_WEBKITGTK_COMPAT_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/linux/webkitgtk/dmabuf.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_GTK_WEBKITGTK_DMABUF_HH\n#define WEBVIEW_BACKENDS_GTK_WEBKITGTK_DMABUF_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n\n#include <cstdlib>\n#include <string>\n\n#include <gtk/gtk.h>\n\n#if GTK_MAJOR_VERSION >= 4\n\n#include <jsc/jsc.h>\n#include <webkit/webkit.h>\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/x11/gdkx.h>\n#endif\n\n#elif GTK_MAJOR_VERSION >= 3\n\n#include <JavaScriptCore/JavaScript.h>\n#include <webkit2/webkit2.h>\n\n#ifdef GDK_WINDOWING_X11\n#include <gdk/gdkx.h>\n#endif\n\n#endif\n\n#include <fcntl.h>\n#include <sys/stat.h>\n\nnamespace webview {\nnamespace detail {\n\n// Namespace containing workaround for WebKit 2.42 when using NVIDIA GPU\n// driver.\n// See WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=261874\n// Please remove all of the code in this namespace when it's no longer needed.\nnamespace webkit_dmabuf {\n\n// Get environment variable. Not thread-safe.\nstatic inline std::string get_env(const std::string &name) {\n  auto *value = std::getenv(name.c_str());\n  if (value) {\n    return {value};\n  }\n  return {};\n}\n\n// Set environment variable. Not thread-safe.\nstatic inline void set_env(const std::string &name, const std::string &value) {\n  ::setenv(name.c_str(), value.c_str(), 1);\n}\n\n// Checks whether the NVIDIA GPU driver is used based on whether the kernel\n// module is loaded.\nstatic inline bool is_using_nvidia_driver() {\n  struct ::stat buffer {};\n  if (::stat(\"/sys/module/nvidia\", &buffer) != 0) {\n    return false;\n  }\n  return S_ISDIR(buffer.st_mode);\n}\n\n// Checks whether the windowing system is Wayland.\nstatic inline bool is_wayland_display() {\n  if (!get_env(\"WAYLAND_DISPLAY\").empty()) {\n    return true;\n  }\n  if (get_env(\"XDG_SESSION_TYPE\") == \"wayland\") {\n    return true;\n  }\n  if (get_env(\"DESKTOP_SESSION\").find(\"wayland\") != std::string::npos) {\n    return true;\n  }\n  return false;\n}\n\n// Checks whether the GDK X11 backend is used.\n// See: https://docs.gtk.org/gdk3/class.DisplayManager.html\nstatic inline bool is_gdk_x11_backend() {\n#ifdef GDK_WINDOWING_X11\n  auto *gdk_display = gdk_display_get_default();\n  return GDK_IS_X11_DISPLAY(gdk_display); // NOLINT(misc-const-correctness)\n#else\n  return false;\n#endif\n}\n\n// Checks whether WebKit is affected by bug when using DMA-BUF renderer.\n// Returns true if all of the following conditions are met:\n//  - WebKit version is >= 2.42 (please narrow this down when there's a fix).\n//  - Environment variables are empty or not set:\n//    - WEBKIT_DISABLE_DMABUF_RENDERER\n//  - Windowing system is not Wayland.\n//  - GDK backend is X11.\n//  - NVIDIA GPU driver is used.\nstatic inline bool is_webkit_dmabuf_bugged() {\n  auto wk_major = webkit_get_major_version();\n  auto wk_minor = webkit_get_minor_version();\n  // TODO: Narrow down affected WebKit version when there's a fixed version\n  auto is_affected_wk_version = wk_major == 2 && wk_minor >= 42;\n  if (!is_affected_wk_version) {\n    return false;\n  }\n  if (!get_env(\"WEBKIT_DISABLE_DMABUF_RENDERER\").empty()) {\n    return false;\n  }\n  if (is_wayland_display()) {\n    return false;\n  }\n  if (!is_gdk_x11_backend()) {\n    return false;\n  }\n  if (!is_using_nvidia_driver()) {\n    return false;\n  }\n  return true;\n}\n\n// Applies workaround for WebKit DMA-BUF bug if needed.\n// See WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=261874\nstatic inline void apply_webkit_dmabuf_workaround() {\n  if (!is_webkit_dmabuf_bugged()) {\n    return;\n  }\n  set_env(\"WEBKIT_DISABLE_DMABUF_RENDERER\", \"1\");\n}\n\n} // namespace webkit_dmabuf\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_GTK_WEBKITGTK_DMABUF_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/com_init_wrapper.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_COM_INIT_WRAPPER_HH\n#define WEBVIEW_PLATFORM_WINDOWS_COM_INIT_WRAPPER_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n//\n// ====================================================================\n//\n// This implementation uses Win32 API to create a native window. It\n// uses Edge/Chromium webview2 backend as a browser engine.\n//\n// ====================================================================\n//\n\n#include \"../../../errors.hh\"\n\n#include <utility>\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#include <objbase.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"ole32.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\n/**\n * A wrapper around COM library initialization. Calls CoInitializeEx in the\n * constructor and CoUninitialize in the destructor.\n *\n * @exception exception Thrown if CoInitializeEx has already been called with a\n * different concurrency model.\n */\nclass com_init_wrapper {\npublic:\n  com_init_wrapper() = default;\n\n  com_init_wrapper(DWORD dwCoInit) {\n    // We can safely continue as long as COM was either successfully\n    // initialized or already initialized.\n    // RPC_E_CHANGED_MODE means that CoInitializeEx was already called with\n    // a different concurrency model.\n    switch (CoInitializeEx(nullptr, dwCoInit)) {\n    case S_OK:\n    case S_FALSE:\n      m_initialized = true;\n      break;\n    case RPC_E_CHANGED_MODE:\n      throw exception{\n          WEBVIEW_ERROR_INVALID_STATE,\n          \"CoInitializeEx already called with a different concurrency model\"};\n    default:\n      throw exception{WEBVIEW_ERROR_UNSPECIFIED,\n                      \"Unexpected result from CoInitializeEx\"};\n    }\n  }\n\n  ~com_init_wrapper() {\n    if (m_initialized) {\n      CoUninitialize();\n      m_initialized = false;\n    }\n  }\n\n  com_init_wrapper(const com_init_wrapper &other) = delete;\n  com_init_wrapper &operator=(const com_init_wrapper &other) = delete;\n\n  com_init_wrapper(com_init_wrapper &&other) noexcept {\n    *this = std::move(other);\n  }\n\n  com_init_wrapper &operator=(com_init_wrapper &&other) noexcept {\n    if (this == &other) {\n      return *this;\n    }\n    m_initialized = other.m_initialized;\n    other.m_initialized = false;\n    return *this;\n  }\n\nprivate:\n  bool m_initialized = false;\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_COM_INIT_WRAPPER_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/dpi.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_DPI_HH\n#define WEBVIEW_PLATFORM_WINDOWS_DPI_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n//\n// ====================================================================\n//\n// This implementation uses Win32 API to create a native window. It\n// uses Edge/Chromium webview2 backend as a browser engine.\n//\n// ====================================================================\n//\n\n#include \"../../native_library.hh\"\n#include \"shcore.hh\"\n#include \"user32.hh\"\n#include \"version.hh\"\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"user32.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\ninline bool is_per_monitor_v2_awareness_available() {\n  // Windows 10, version 1703\n  return compare_os_version(10, 0, 15063) >= 0;\n}\n\ninline bool enable_dpi_awareness() {\n  auto user32 = native_library(L\"user32.dll\");\n  if (auto fn = user32.get(user32_symbols::SetProcessDpiAwarenessContext)) {\n    auto dpi_awareness =\n        reinterpret_cast<user32_symbols::DPI_AWARENESS_CONTEXT>(\n            is_per_monitor_v2_awareness_available()\n                ? user32_symbols::dpi_awareness::per_monitor_v2_aware\n                : user32_symbols::dpi_awareness::per_monitor_aware);\n    if (fn(dpi_awareness)) {\n      return true;\n    }\n    return GetLastError() == ERROR_ACCESS_DENIED;\n  }\n  if (auto shcore = native_library(L\"shcore.dll\")) {\n    if (auto fn = shcore.get(shcore_symbols::SetProcessDpiAwareness)) {\n      auto result = fn(shcore_symbols::PROCESS_PER_MONITOR_DPI_AWARE);\n      return result == S_OK || result == E_ACCESSDENIED;\n    }\n  }\n  if (auto fn = user32.get(user32_symbols::SetProcessDPIAware)) {\n    return !!fn();\n  }\n  return true;\n}\n\ninline bool enable_non_client_dpi_scaling_if_needed(HWND window) {\n  auto user32 = native_library(L\"user32.dll\");\n  auto get_ctx_fn = user32.get(user32_symbols::GetWindowDpiAwarenessContext);\n  if (!get_ctx_fn) {\n    return true;\n  }\n  auto awareness = get_ctx_fn(window);\n  if (!awareness) {\n    return false;\n  }\n  auto ctx_equal_fn = user32.get(user32_symbols::AreDpiAwarenessContextsEqual);\n  if (!ctx_equal_fn) {\n    return true;\n  }\n  // EnableNonClientDpiScaling is only needed with per monitor v1 awareness.\n  auto per_monitor = reinterpret_cast<user32_symbols::DPI_AWARENESS_CONTEXT>(\n      user32_symbols::dpi_awareness::per_monitor_aware);\n  if (!ctx_equal_fn(awareness, per_monitor)) {\n    return true;\n  }\n  auto enable_fn = user32.get(user32_symbols::EnableNonClientDpiScaling);\n  if (!enable_fn) {\n    return true;\n  }\n  return !!enable_fn(window);\n}\n\nconstexpr int get_default_window_dpi() {\n  return 96; // USER_DEFAULT_SCREEN_DPI\n}\n\ninline int get_window_dpi(HWND window) {\n  auto user32 = native_library(L\"user32.dll\");\n  if (auto fn = user32.get(user32_symbols::GetDpiForWindow)) {\n    auto dpi = static_cast<int>(fn(window));\n    return dpi;\n  }\n  return get_default_window_dpi();\n}\n\nconstexpr int scale_value_for_dpi(int value, int from_dpi, int to_dpi) {\n  return (value * to_dpi) / from_dpi;\n}\n\nconstexpr SIZE scale_size(int width, int height, int from_dpi, int to_dpi) {\n  return {scale_value_for_dpi(width, from_dpi, to_dpi),\n          scale_value_for_dpi(height, from_dpi, to_dpi)};\n}\n\ninline SIZE make_window_frame_size(HWND window, int width, int height,\n                                   int dpi) {\n  auto style = GetWindowLong(window, GWL_STYLE);\n  RECT r{0, 0, width, height};\n  auto user32 = native_library(L\"user32.dll\");\n  if (auto fn = user32.get(user32_symbols::AdjustWindowRectExForDpi)) {\n    fn(&r, style, FALSE, 0, static_cast<UINT>(dpi));\n  } else {\n    AdjustWindowRect(&r, style, 0);\n  }\n  auto frame_width = r.right - r.left;\n  auto frame_height = r.bottom - r.top;\n  return {frame_width, frame_height};\n}\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_DPI_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/dwmapi.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_DWMAPI_HH\n#define WEBVIEW_PLATFORM_WINDOWS_DWMAPI_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"../../native_library.hh\"\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\nnamespace webview {\nnamespace detail {\nnamespace dwmapi_symbols {\n\ntypedef enum {\n  // This undocumented value is used instead of DWMWA_USE_IMMERSIVE_DARK_MODE\n  // on Windows 10 older than build 19041 (2004/20H1).\n  DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_V10_0_19041 = 19,\n  // Documented as being supported since Windows 11 build 22000 (21H2) but it\n  // works since Windows 10 build 19041 (2004/20H1).\n  DWMWA_USE_IMMERSIVE_DARK_MODE = 20\n} DWMWINDOWATTRIBUTE;\n\nusing DwmSetWindowAttribute_t = HRESULT(WINAPI *)(HWND, DWORD, LPCVOID, DWORD);\n\nconstexpr auto DwmSetWindowAttribute =\n    library_symbol<DwmSetWindowAttribute_t>(\"DwmSetWindowAttribute\");\n\n} // namespace dwmapi_symbols\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_DWMAPI_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/iid.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_IID_HH\n#define WEBVIEW_PLATFORM_WINDOWS_IID_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#include <objbase.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"ole32.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\ntemplate <typename T> struct cast_info_t {\n  using type = T;\n  IID iid;\n};\n\n// Checks whether the specified IID equals the IID of the specified type and\n// if so casts the \"this\" pointer to T and returns it. Returns nullptr on\n// mismatching IIDs.\n// If ppv is specified then the pointer will also be assigned to *ppv.\ntemplate <typename From, typename To>\nTo *cast_if_equal_iid(From *from, REFIID riid, const cast_info_t<To> &info,\n                      LPVOID *ppv = nullptr) noexcept {\n  To *ptr = nullptr;\n  if (IsEqualIID(riid, info.iid)) {\n    ptr = static_cast<To *>(from);\n    ptr->AddRef();\n  }\n  if (ppv) {\n    *ppv = ptr;\n  }\n  return ptr;\n}\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_IID_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/ntdll.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_NTDLL_HH\n#define WEBVIEW_PLATFORM_WINDOWS_NTDLL_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"../../native_library.hh\"\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\nnamespace webview {\nnamespace detail {\nnamespace ntdll_symbols {\n\nusing RtlGetVersion_t =\n    unsigned int /*NTSTATUS*/ (WINAPI *)(RTL_OSVERSIONINFOW *);\n\nconstexpr auto RtlGetVersion = library_symbol<RtlGetVersion_t>(\"RtlGetVersion\");\n\n} // namespace ntdll_symbols\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_NTDLL_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/reg_key.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_REG_KEY_HH\n#define WEBVIEW_PLATFORM_WINDOWS_REG_KEY_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include <string>\n#include <vector>\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"advapi32.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\nclass reg_key {\npublic:\n  explicit reg_key(HKEY root_key, const wchar_t *sub_key, DWORD options,\n                   REGSAM sam_desired) {\n    HKEY handle;\n    auto status =\n        RegOpenKeyExW(root_key, sub_key, options, sam_desired, &handle);\n    if (status == ERROR_SUCCESS) {\n      m_handle = handle;\n    }\n  }\n\n  explicit reg_key(HKEY root_key, const std::wstring &sub_key, DWORD options,\n                   REGSAM sam_desired)\n      : reg_key(root_key, sub_key.c_str(), options, sam_desired) {}\n\n  virtual ~reg_key() {\n    if (m_handle) {\n      RegCloseKey(m_handle);\n      m_handle = nullptr;\n    }\n  }\n\n  reg_key(const reg_key &other) = delete;\n  reg_key &operator=(const reg_key &other) = delete;\n  reg_key(reg_key &&other) = delete;\n  reg_key &operator=(reg_key &&other) = delete;\n\n  bool is_open() const { return !!m_handle; }\n  bool get_handle() const { return m_handle; }\n\n  template <typename Container>\n  void query_bytes(const wchar_t *name, Container &result) const {\n    DWORD buf_length = 0;\n    // Get the size of the data in bytes.\n    auto status = RegQueryValueExW(m_handle, name, nullptr, nullptr, nullptr,\n                                   &buf_length);\n    if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) {\n      result.resize(0);\n      return;\n    }\n    // Read the data.\n    result.resize(buf_length / sizeof(typename Container::value_type));\n    auto *buf = reinterpret_cast<LPBYTE>(&result[0]);\n    status =\n        RegQueryValueExW(m_handle, name, nullptr, nullptr, buf, &buf_length);\n    if (status != ERROR_SUCCESS) {\n      result.resize(0);\n      return;\n    }\n  }\n\n  std::wstring query_string(const wchar_t *name) const {\n    std::wstring result;\n    query_bytes(name, result);\n    // Remove trailing null-characters.\n    for (std::size_t length = result.size(); length > 0; --length) {\n      if (result[length - 1] != 0) {\n        result.resize(length);\n        break;\n      }\n    }\n    return result;\n  }\n\n  unsigned int query_uint(const wchar_t *name,\n                          unsigned int default_value) const {\n    std::vector<char> data;\n    query_bytes(name, data);\n    if (data.size() < sizeof(DWORD)) {\n      return default_value;\n    }\n    return static_cast<unsigned int>(*reinterpret_cast<DWORD *>(data.data()));\n  }\n\nprivate:\n  HKEY m_handle = nullptr;\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_REG_KEY_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/shcore.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_SHCORE_HH\n#define WEBVIEW_PLATFORM_WINDOWS_SHCORE_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"../../native_library.hh\"\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\nnamespace webview {\nnamespace detail {\nnamespace shcore_symbols {\n\ntypedef enum { PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;\nusing SetProcessDpiAwareness_t = HRESULT(WINAPI *)(PROCESS_DPI_AWARENESS);\n\nconstexpr auto SetProcessDpiAwareness =\n    library_symbol<SetProcessDpiAwareness_t>(\"SetProcessDpiAwareness\");\n\n} // namespace shcore_symbols\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_SHCORE_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/theme.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_THEME_HH\n#define WEBVIEW_PLATFORM_WINDOWS_THEME_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"../../native_library.hh\"\n#include \"dwmapi.hh\"\n#include \"reg_key.hh\"\n\nnamespace webview {\nnamespace detail {\n\ninline bool is_dark_theme_enabled() {\n  constexpr auto *sub_key =\n      L\"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Themes\\\\Personalize\";\n  reg_key key(HKEY_CURRENT_USER, sub_key, 0, KEY_READ);\n  if (!key.is_open()) {\n    // Default is light theme\n    return false;\n  }\n  return key.query_uint(L\"AppsUseLightTheme\", 1) == 0;\n}\n\ninline void apply_window_theme(HWND window) {\n  auto dark_theme_enabled = is_dark_theme_enabled();\n\n  // Use \"immersive dark mode\" on systems that support it.\n  // Changes the color of the window's title bar (light or dark).\n  BOOL use_dark_mode{dark_theme_enabled ? TRUE : FALSE};\n  static native_library dwmapi{L\"dwmapi.dll\"};\n  if (auto fn = dwmapi.get(dwmapi_symbols::DwmSetWindowAttribute)) {\n    // Try the modern, documented attribute before the older, undocumented one.\n    if (fn(window, dwmapi_symbols::DWMWA_USE_IMMERSIVE_DARK_MODE,\n           &use_dark_mode, sizeof(use_dark_mode)) != S_OK) {\n      fn(window,\n         dwmapi_symbols::DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_V10_0_19041,\n         &use_dark_mode, sizeof(use_dark_mode));\n    }\n  }\n}\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_THEME_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/user32.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_USER32_HH\n#define WEBVIEW_PLATFORM_WINDOWS_USER32_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"../../native_library.hh\"\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\nnamespace webview {\nnamespace detail {\nnamespace user32_symbols {\n\nusing DPI_AWARENESS_CONTEXT = HANDLE;\nusing SetProcessDpiAwarenessContext_t = BOOL(WINAPI *)(DPI_AWARENESS_CONTEXT);\nusing SetProcessDPIAware_t = BOOL(WINAPI *)();\nusing GetDpiForWindow_t = UINT(WINAPI *)(HWND);\nusing EnableNonClientDpiScaling_t = BOOL(WINAPI *)(HWND);\nusing AdjustWindowRectExForDpi_t = BOOL(WINAPI *)(LPRECT, DWORD, BOOL, DWORD,\n                                                  UINT);\nusing GetWindowDpiAwarenessContext_t = DPI_AWARENESS_CONTEXT(WINAPI *)(HWND);\nusing AreDpiAwarenessContextsEqual_t = BOOL(WINAPI *)(DPI_AWARENESS_CONTEXT,\n                                                      DPI_AWARENESS_CONTEXT);\n\n// Use intptr_t as the underlying type because we need to\n// reinterpret_cast<DPI_AWARENESS_CONTEXT> which is a pointer.\n// Available since Windows 10, version 1607\nenum class dpi_awareness : intptr_t {\n  per_monitor_v2_aware = -4, // Available since Windows 10, version 1703\n  per_monitor_aware = -3\n};\n\nconstexpr auto SetProcessDpiAwarenessContext =\n    library_symbol<SetProcessDpiAwarenessContext_t>(\n        \"SetProcessDpiAwarenessContext\");\nconstexpr auto SetProcessDPIAware =\n    library_symbol<SetProcessDPIAware_t>(\"SetProcessDPIAware\");\nconstexpr auto GetDpiForWindow =\n    library_symbol<GetDpiForWindow_t>(\"GetDpiForWindow\");\nconstexpr auto EnableNonClientDpiScaling =\n    library_symbol<EnableNonClientDpiScaling_t>(\"EnableNonClientDpiScaling\");\nconstexpr auto AdjustWindowRectExForDpi =\n    library_symbol<AdjustWindowRectExForDpi_t>(\"AdjustWindowRectExForDpi\");\nconstexpr auto GetWindowDpiAwarenessContext =\n    library_symbol<GetWindowDpiAwarenessContext_t>(\n        \"GetWindowDpiAwarenessContext\");\nconstexpr auto AreDpiAwarenessContextsEqual =\n    library_symbol<AreDpiAwarenessContextsEqual_t>(\n        \"AreDpiAwarenessContextsEqual\");\n\n} // namespace user32_symbols\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_USER32_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/version.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_PLATFORM_WINDOWS_VERSION_HH\n#define WEBVIEW_PLATFORM_WINDOWS_VERSION_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS)\n\n#include \"ntdll.hh\"\n\n#include <array>\n#include <string>\n#include <vector>\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"version.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\n// Parses a version string with 1-4 integral components, e.g. \"1.2.3.4\".\n// Missing or invalid components default to 0, and excess components are ignored.\ntemplate <typename T>\nstd::array<unsigned int, 4>\nparse_version(const std::basic_string<T> &version) noexcept {\n  using iterator = typename std::basic_string<T>::const_iterator;\n  auto parse_component = [](iterator sb, iterator se) -> unsigned int {\n    try {\n      auto n = std::stol(std::basic_string<T>(sb, se));\n      return n < 0 ? 0 : n;\n    } catch (std::exception &) {\n      return 0;\n    }\n  };\n  auto end = version.end();\n  auto sb = version.begin(); // subrange begin\n  auto se = sb;              // subrange end\n  unsigned int ci = 0;       // component index\n  std::array<unsigned int, 4> components{};\n  while (sb != end && se != end && ci < components.size()) {\n    if (*se == static_cast<T>('.')) {\n      components[ci++] = parse_component(sb, se);\n      sb = ++se;\n      continue;\n    }\n    ++se;\n  }\n  if (sb < se && ci < components.size()) {\n    components[ci] = parse_component(sb, se);\n  }\n  return components;\n}\n\ntemplate <typename T, std::size_t Length>\nstd::array<unsigned int, 4> parse_version(const T (&version)[Length]) noexcept {\n  return parse_version(std::basic_string<T>(version, Length));\n}\n\ninline std::wstring\nget_file_version_string(const std::wstring &file_path) noexcept {\n  DWORD dummy_handle; // Unused\n  DWORD info_buffer_length =\n      GetFileVersionInfoSizeW(file_path.c_str(), &dummy_handle);\n  if (info_buffer_length == 0) {\n    return std::wstring();\n  }\n  std::vector<char> info_buffer;\n  info_buffer.reserve(info_buffer_length);\n  if (!GetFileVersionInfoW(file_path.c_str(), 0, info_buffer_length,\n                           info_buffer.data())) {\n    return std::wstring();\n  }\n  auto sub_block = L\"\\\\StringFileInfo\\\\040904B0\\\\ProductVersion\";\n  LPWSTR version = nullptr;\n  unsigned int version_length = 0;\n  if (!VerQueryValueW(info_buffer.data(), sub_block,\n                      reinterpret_cast<LPVOID *>(&version), &version_length)) {\n    return std::wstring();\n  }\n  if (!version || version_length == 0) {\n    return std::wstring();\n  }\n  return std::wstring(version, version_length);\n}\n\n// Compare the specified version against the OS version.\n// Returns less than 0 if the OS version is less.\n// Returns 0 if the versions are equal.\n// Returns greater than 0 if the specified version is greater.\ninline int compare_os_version(unsigned int major, unsigned int minor,\n                              unsigned int build) {\n  // Use RtlGetVersion both to bypass potential issues related to\n  // VerifyVersionInfo and manifests, and because both GetVersion and\n  // GetVersionEx are deprecated.\n  auto ntdll = native_library(L\"ntdll.dll\");\n  if (auto fn = ntdll.get(ntdll_symbols::RtlGetVersion)) {\n    RTL_OSVERSIONINFOW vi{};\n    vi.dwOSVersionInfoSize = sizeof(vi);\n    if (fn(&vi) != 0) {\n      return false;\n    }\n    if (vi.dwMajorVersion == major) {\n      if (vi.dwMinorVersion == minor) {\n        return static_cast<int>(vi.dwBuildNumber) - static_cast<int>(build);\n      }\n      return static_cast<int>(vi.dwMinorVersion) - static_cast<int>(minor);\n    }\n    return static_cast<int>(vi.dwMajorVersion) - static_cast<int>(major);\n  }\n  return false;\n}\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_PLATFORM_WINDOWS_VERSION_HH\n"
  },
  {
    "path": "core/include/webview/detail/platform/windows/webview2/loader.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_BACKENDS_WEBVIEW2_LOADER_HH\n#define WEBVIEW_BACKENDS_WEBVIEW2_LOADER_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"../../../../macros.h\"\n\n#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)\n\n#include \"../../../native_library.hh\"\n#include \"../iid.hh\"\n#include \"../reg_key.hh\"\n#include \"../version.hh\"\n\n#include <string>\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n#include <windows.h>\n\n#include <objbase.h>\n\n#include \"WebView2.h\" // amalgamate(skip)\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"ole32.lib\")\n#endif\n\nnamespace webview {\nnamespace detail {\n\n// Enable built-in WebView2Loader implementation by default.\n#ifndef WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL\n#define WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL 1\n#endif\n\n// Link WebView2Loader.dll explicitly by default only if the built-in\n// implementation is enabled.\n#ifndef WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK\n#define WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL\n#endif\n\n// Explicit linking of WebView2Loader.dll should be used along with\n// the built-in implementation.\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1 &&                                    \\\n    WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK != 1\n#undef WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK\n#error Please set WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK=1.\n#endif\n\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1\n// Gets the last component of a Windows native file path.\n// For example, if the path is \"C:\\a\\b\" then the result is \"b\".\ntemplate <typename T>\nstd::basic_string<T>\nget_last_native_path_component(const std::basic_string<T> &path) {\n  auto pos = path.find_last_of(static_cast<T>('\\\\'));\n  if (pos != std::basic_string<T>::npos) {\n    return path.substr(pos + 1);\n  }\n  return std::basic_string<T>();\n}\n#endif // WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL\n\nnamespace mswebview2 {\nstatic constexpr IID\n    IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler{\n        0x6C4819F3,\n        0xC9B7,\n        0x4260,\n        {0x81, 0x27, 0xC9, 0xF5, 0xBD, 0xE7, 0xF6, 0x8C}};\nstatic constexpr IID\n    IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler{\n        0x4E8A3389,\n        0xC9D8,\n        0x4BD2,\n        {0xB6, 0xB5, 0x12, 0x4F, 0xEE, 0x6C, 0xC1, 0x4D}};\nstatic constexpr IID IID_ICoreWebView2PermissionRequestedEventHandler{\n    0x15E1C6A3,\n    0xC72A,\n    0x4DF3,\n    {0x91, 0xD7, 0xD0, 0x97, 0xFB, 0xEC, 0x6B, 0xFD}};\nstatic constexpr IID IID_ICoreWebView2WebMessageReceivedEventHandler{\n    0x57213F19,\n    0x00E6,\n    0x49FA,\n    {0x8E, 0x07, 0x89, 0x8E, 0xA0, 0x1E, 0xCB, 0xD2}};\nstatic constexpr IID\n    IID_ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler{\n        0xB99369F3,\n        0x9B11,\n        0x47B5,\n        {0xBC, 0x6F, 0x8E, 0x78, 0x95, 0xFC, 0xEA, 0x17}};\n\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1\nenum class webview2_runtime_type { installed = 0, embedded = 1 };\n\nnamespace webview2_symbols {\nusing CreateWebViewEnvironmentWithOptionsInternal_t =\n    HRESULT(STDMETHODCALLTYPE *)(\n        bool, webview2_runtime_type, PCWSTR, IUnknown *,\n        ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler *);\nusing DllCanUnloadNow_t = HRESULT(STDMETHODCALLTYPE *)();\n\nstatic constexpr auto CreateWebViewEnvironmentWithOptionsInternal =\n    library_symbol<CreateWebViewEnvironmentWithOptionsInternal_t>(\n        \"CreateWebViewEnvironmentWithOptionsInternal\");\nstatic constexpr auto DllCanUnloadNow =\n    library_symbol<DllCanUnloadNow_t>(\"DllCanUnloadNow\");\n} // namespace webview2_symbols\n#endif // WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL\n\n#if WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK == 1\nnamespace webview2_symbols {\nusing CreateCoreWebView2EnvironmentWithOptions_t = HRESULT(STDMETHODCALLTYPE *)(\n    PCWSTR, PCWSTR, ICoreWebView2EnvironmentOptions *,\n    ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler *);\nusing GetAvailableCoreWebView2BrowserVersionString_t =\n    HRESULT(STDMETHODCALLTYPE *)(PCWSTR, LPWSTR *);\n\nstatic constexpr auto CreateCoreWebView2EnvironmentWithOptions =\n    library_symbol<CreateCoreWebView2EnvironmentWithOptions_t>(\n        \"CreateCoreWebView2EnvironmentWithOptions\");\nstatic constexpr auto GetAvailableCoreWebView2BrowserVersionString =\n    library_symbol<GetAvailableCoreWebView2BrowserVersionString_t>(\n        \"GetAvailableCoreWebView2BrowserVersionString\");\n} // namespace webview2_symbols\n#endif // WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK\n\nclass loader {\npublic:\n  HRESULT create_environment_with_options(\n      PCWSTR browser_dir, PCWSTR user_data_dir,\n      ICoreWebView2EnvironmentOptions *env_options,\n      ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler\n          *created_handler) const {\n#if WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK == 1\n    if (m_lib.is_loaded()) {\n      if (auto fn = m_lib.get(\n              webview2_symbols::CreateCoreWebView2EnvironmentWithOptions)) {\n        return fn(browser_dir, user_data_dir, env_options, created_handler);\n      }\n    }\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1\n    return create_environment_with_options_impl(browser_dir, user_data_dir,\n                                                env_options, created_handler);\n#else\n    return S_FALSE;\n#endif\n#else\n    return ::CreateCoreWebView2EnvironmentWithOptions(\n        browser_dir, user_data_dir, env_options, created_handler);\n#endif // WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK\n  }\n\n  HRESULT\n  get_available_browser_version_string(PCWSTR browser_dir,\n                                       LPWSTR *version) const {\n#if WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK == 1\n    if (m_lib.is_loaded()) {\n      if (auto fn = m_lib.get(\n              webview2_symbols::GetAvailableCoreWebView2BrowserVersionString)) {\n        return fn(browser_dir, version);\n      }\n    }\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1\n    return get_available_browser_version_string_impl(browser_dir, version);\n#else\n    return S_FALSE;\n#endif\n#else\n    return ::GetAvailableCoreWebView2BrowserVersionString(browser_dir, version);\n#endif // WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK\n  }\n\nprivate:\n#if WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL == 1\n  struct client_info_t {\n    bool found{};\n    std::wstring dll_path;\n    std::wstring version;\n    webview2_runtime_type runtime_type{};\n\n    client_info_t() = default;\n\n    client_info_t(bool found, std::wstring dll_path, std::wstring version,\n                  webview2_runtime_type runtime_type)\n        : found{found},\n          dll_path{std::move(dll_path)},\n          version{std::move(version)},\n          runtime_type{runtime_type} {}\n  };\n\n  HRESULT create_environment_with_options_impl(\n      PCWSTR browser_dir, PCWSTR user_data_dir,\n      ICoreWebView2EnvironmentOptions *env_options,\n      ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler\n          *created_handler) const {\n    auto found_client = find_available_client(browser_dir);\n    if (!found_client.found) {\n      return -1;\n    }\n    auto client_dll = native_library(found_client.dll_path);\n    if (auto fn = client_dll.get(\n            webview2_symbols::CreateWebViewEnvironmentWithOptionsInternal)) {\n      return fn(true, found_client.runtime_type, user_data_dir, env_options,\n                created_handler);\n    }\n    if (auto fn = client_dll.get(webview2_symbols::DllCanUnloadNow)) {\n      if (!fn()) {\n        client_dll.detach();\n      }\n    }\n    return ERROR_SUCCESS;\n  }\n\n  HRESULT\n  get_available_browser_version_string_impl(PCWSTR browser_dir,\n                                            LPWSTR *version) const {\n    if (!version) {\n      return -1;\n    }\n    auto found_client = find_available_client(browser_dir);\n    if (!found_client.found) {\n      return -1;\n    }\n    auto info_length_bytes =\n        found_client.version.size() * sizeof(found_client.version[0]);\n    auto info = static_cast<LPWSTR>(CoTaskMemAlloc(info_length_bytes));\n    if (!info) {\n      return -1;\n    }\n    CopyMemory(info, found_client.version.c_str(), info_length_bytes);\n    *version = info;\n    return 0;\n  }\n\n  client_info_t find_available_client(PCWSTR browser_dir) const {\n    if (browser_dir) {\n      return find_embedded_client(api_version, browser_dir);\n    }\n    auto found_client =\n        find_installed_client(api_version, true, default_release_channel_guid);\n    if (!found_client.found) {\n      found_client = find_installed_client(api_version, false,\n                                           default_release_channel_guid);\n    }\n    return found_client;\n  }\n\n  std::wstring make_client_dll_path(const std::wstring &dir) const {\n    auto dll_path = dir;\n    if (!dll_path.empty()) {\n      auto last_char = dir[dir.size() - 1];\n      if (last_char != L'\\\\' && last_char != L'/') {\n        dll_path += L'\\\\';\n      }\n    }\n    dll_path += L\"EBWebView\\\\\";\n#if defined(_M_X64) || defined(__x86_64__)\n    dll_path += L\"x64\";\n#elif defined(_M_IX86) || defined(__i386__)\n    dll_path += L\"x86\";\n#elif defined(_M_ARM64) || defined(__aarch64__)\n    dll_path += L\"arm64\";\n#else\n#error WebView2 integration for this platform is not yet supported.\n#endif\n    dll_path += L\"\\\\EmbeddedBrowserWebView.dll\";\n    return dll_path;\n  }\n\n  client_info_t\n  find_installed_client(unsigned int min_api_version, bool system,\n                        const std::wstring &release_channel) const {\n    std::wstring sub_key = client_state_reg_sub_key;\n    sub_key += release_channel;\n    auto root_key = system ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n    reg_key key(root_key, sub_key, 0, KEY_READ | KEY_WOW64_32KEY);\n    if (!key.is_open()) {\n      return {};\n    }\n    auto ebwebview_value = key.query_string(L\"EBWebView\");\n\n    auto client_version_string =\n        get_last_native_path_component(ebwebview_value);\n    auto client_version = parse_version(client_version_string);\n    if (client_version[2] < min_api_version) {\n      // Our API version is greater than the runtime API version.\n      return {};\n    }\n\n    auto client_dll_path = make_client_dll_path(ebwebview_value);\n    return {true, std::move(client_dll_path), std::move(client_version_string),\n            webview2_runtime_type::installed};\n  }\n\n  client_info_t find_embedded_client(unsigned int min_api_version,\n                                     const std::wstring &dir) const {\n    auto client_dll_path = make_client_dll_path(dir);\n\n    auto client_version_string = get_file_version_string(client_dll_path);\n    auto client_version = parse_version(client_version_string);\n    if (client_version[2] < min_api_version) {\n      // Our API version is greater than the runtime API version.\n      return {};\n    }\n\n    return {true, std::move(client_dll_path), std::move(client_version_string),\n            webview2_runtime_type::embedded};\n  }\n\n  // The minimum WebView2 API version we need regardless of the SDK release\n  // actually used. The number comes from the SDK release version,\n  // e.g. 1.0.1150.38. To be safe the SDK should have a number that is greater\n  // than or equal to this number. The Edge browser webview client must\n  // have a number greater than or equal to this number.\n  static constexpr unsigned int api_version = 1150;\n\n  static constexpr auto client_state_reg_sub_key =\n      L\"SOFTWARE\\\\Microsoft\\\\EdgeUpdate\\\\ClientState\\\\\";\n\n  // GUID for the stable release channel.\n  static constexpr auto stable_release_guid =\n      L\"{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\";\n\n  static constexpr auto default_release_channel_guid = stable_release_guid;\n#endif // WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL\n\n#if WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK == 1\n  native_library m_lib{L\"WebView2Loader.dll\"};\n#endif\n};\n\nnamespace cast_info {\nstatic constexpr auto controller_completed =\n    cast_info_t<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>{\n        IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler};\n\nstatic constexpr auto environment_completed =\n    cast_info_t<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>{\n        IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler};\n\nstatic constexpr auto message_received =\n    cast_info_t<ICoreWebView2WebMessageReceivedEventHandler>{\n        IID_ICoreWebView2WebMessageReceivedEventHandler};\n\nstatic constexpr auto permission_requested =\n    cast_info_t<ICoreWebView2PermissionRequestedEventHandler>{\n        IID_ICoreWebView2PermissionRequestedEventHandler};\n\nstatic constexpr auto add_script_to_execute_on_document_created_completed =\n    cast_info_t<\n        ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>{\n        IID_ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler};\n} // namespace cast_info\n\n} // namespace mswebview2\n} // namespace detail\n} // namespace webview\n\n#endif // defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_BACKENDS_WEBVIEW2_LOADER_HH\n"
  },
  {
    "path": "core/include/webview/detail/user_script.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_USER_SCRIPT_HH\n#define WEBVIEW_DETAIL_USER_SCRIPT_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <utility>\n\nnamespace webview {\nnamespace detail {\n\nclass user_script {\npublic:\n  class impl;\n  using impl_deleter = std::function<void(impl *)>;\n  using impl_ptr = std::unique_ptr<impl, impl_deleter>;\n\n  user_script(const std::string &code, impl_ptr &&impl_)\n      : m_code{code}, m_impl{std::move(impl_)} {}\n\n  user_script(const user_script &other) = delete;\n  user_script &operator=(const user_script &other) = delete;\n  user_script(user_script &&other) noexcept { *this = std::move(other); }\n\n  user_script &operator=(user_script &&other) noexcept {\n    if (this == &other) {\n      return *this;\n    }\n    m_code = std::move(other.m_code);\n    m_impl = std::move(other.m_impl);\n    return *this;\n  }\n\n  const std::string &get_code() const { return m_code; }\n\n  impl &get_impl() { return *m_impl; }\n\n  const impl &get_impl() const { return *m_impl; }\n\nprivate:\n  std::string m_code;\n  impl_ptr m_impl;\n};\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_USER_SCRIPT_HH\n"
  },
  {
    "path": "core/include/webview/detail/utility/string.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_DETAIL_UTILITY_STRING_HH\n#define WEBVIEW_DETAIL_UTILITY_STRING_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include <string>\n\n#if defined(_WIN32)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#include <windows.h>\n#endif\n\nnamespace webview {\nnamespace detail {\n\n#if defined(_WIN32)\n// Converts a narrow (UTF-8-encoded) string into a wide (UTF-16-encoded) string.\ninline std::wstring widen_string(const std::string &input) {\n  if (input.empty()) {\n    return std::wstring();\n  }\n  UINT cp = CP_UTF8;\n  DWORD flags = MB_ERR_INVALID_CHARS;\n  auto input_c = input.c_str();\n  auto input_length = static_cast<int>(input.size());\n  auto required_length =\n      MultiByteToWideChar(cp, flags, input_c, input_length, nullptr, 0);\n  if (required_length > 0) {\n    std::wstring output(static_cast<std::size_t>(required_length), L'\\0');\n    if (MultiByteToWideChar(cp, flags, input_c, input_length, &output[0],\n                            required_length) > 0) {\n      return output;\n    }\n  }\n  // Failed to convert string from UTF-8 to UTF-16\n  return std::wstring();\n}\n\n// Converts a wide (UTF-16-encoded) string into a narrow (UTF-8-encoded) string.\ninline std::string narrow_string(const std::wstring &input) {\n  struct wc_flags {\n    enum TYPE : unsigned int {\n      // WC_ERR_INVALID_CHARS\n      err_invalid_chars = 0x00000080U\n    };\n  };\n  if (input.empty()) {\n    return std::string();\n  }\n  UINT cp = CP_UTF8;\n  DWORD flags = wc_flags::err_invalid_chars;\n  auto input_c = input.c_str();\n  auto input_length = static_cast<int>(input.size());\n  auto required_length = WideCharToMultiByte(cp, flags, input_c, input_length,\n                                             nullptr, 0, nullptr, nullptr);\n  if (required_length > 0) {\n    std::string output(static_cast<std::size_t>(required_length), '\\0');\n    if (WideCharToMultiByte(cp, flags, input_c, input_length, &output[0],\n                            required_length, nullptr, nullptr) > 0) {\n      return output;\n    }\n  }\n  // Failed to convert string from UTF-16 to UTF-8\n  return std::string();\n}\n#endif\n\n} // namespace detail\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_DETAIL_UTILITY_STRING_HH\n"
  },
  {
    "path": "core/include/webview/errors.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_ERRORS_H\n#define WEBVIEW_ERRORS_H\n\n/// @name Errors\n/// @{\n\n/**\n * @brief Error codes returned to callers of the API.\n *\n * The following codes are commonly used in the library:\n * - @c WEBVIEW_ERROR_OK\n * - @c WEBVIEW_ERROR_UNSPECIFIED\n * - @c WEBVIEW_ERROR_INVALID_ARGUMENT\n * - @c WEBVIEW_ERROR_INVALID_STATE\n *\n * With the exception of @c WEBVIEW_ERROR_OK which is normally expected,\n * the other common codes do not normally need to be handled specifically.\n * Refer to specific functions regarding handling of other codes.\n */\ntypedef enum {\n  /// Missing dependency.\n  WEBVIEW_ERROR_MISSING_DEPENDENCY = -5,\n  /// Operation canceled.\n  WEBVIEW_ERROR_CANCELED = -4,\n  /// Invalid state detected.\n  WEBVIEW_ERROR_INVALID_STATE = -3,\n  /// One or more invalid arguments have been specified e.g. in a function call.\n  WEBVIEW_ERROR_INVALID_ARGUMENT = -2,\n  /// An unspecified error occurred. A more specific error code may be needed.\n  WEBVIEW_ERROR_UNSPECIFIED = -1,\n  /// OK/Success. Functions that return error codes will typically return this\n  /// to signify successful operations.\n  WEBVIEW_ERROR_OK = 0,\n  /// Signifies that something already exists.\n  WEBVIEW_ERROR_DUPLICATE = 1,\n  /// Signifies that something does not exist.\n  WEBVIEW_ERROR_NOT_FOUND = 2\n} webview_error_t;\n\n/// @}\n\n#endif // WEBVIEW_ERRORS_H\n"
  },
  {
    "path": "core/include/webview/errors.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_ERRORS_HH\n#define WEBVIEW_ERRORS_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"errors.h\"\n\n#include <exception>\n#include <string>\n\nnamespace webview {\n\nclass error_info {\npublic:\n  error_info(webview_error_t code, const std::string &message = {}) noexcept\n      : m_code{code}, m_message{message} {}\n  error_info() = default;\n\n  webview_error_t code() const { return m_code; }\n  const std::string &message() const { return m_message; }\n\nprivate:\n  webview_error_t m_code{WEBVIEW_ERROR_UNSPECIFIED};\n  std::string m_message;\n};\n\nclass exception : public std::exception {\npublic:\n  exception(webview_error_t code, const std::string &message,\n            std::exception_ptr cause) noexcept\n      : exception{error_info{code, message}, cause} {}\n\n  exception(webview_error_t code, const std::string &message) noexcept\n      : exception{error_info{code, message}} {}\n\n  exception(const error_info &error, std::exception_ptr cause) noexcept\n      : m_error{error},\n        // NOLINTNEXTLINE(bugprone-throw-keyword-missing)\n        m_cause{cause} {}\n\n  exception(const error_info &error) noexcept : m_error{error} {}\n\n  exception() = default;\n\n  const error_info &error() const { return m_error; }\n  std::exception_ptr cause() const { return m_cause; }\n\n  const char *what() const noexcept override {\n    return m_error.message().c_str();\n  }\n\nprivate:\n  error_info m_error{WEBVIEW_ERROR_UNSPECIFIED};\n  std::exception_ptr m_cause;\n};\n\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_ERRORS_HH\n"
  },
  {
    "path": "core/include/webview/json_deprecated.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_JSON_HH\n#define WEBVIEW_JSON_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"detail/json.hh\"\n#include \"macros.h\"\n\nnamespace webview {\n\nWEBVIEW_DEPRECATED_PRIVATE\ninline int json_parse_c(const char *s, size_t sz, const char *key, size_t keysz,\n                        const char **value, size_t *valuesz) {\n  return detail::json_parse_c(s, sz, key, keysz, value, valuesz);\n}\n\nWEBVIEW_DEPRECATED_PRIVATE\ninline std::string json_escape(const std::string &s) {\n  return detail::json_escape(s);\n}\n\nWEBVIEW_DEPRECATED_PRIVATE\ninline int json_unescape(const char *s, size_t n, char *out) {\n  return detail::json_unescape(s, n, out);\n}\n\nWEBVIEW_DEPRECATED_PRIVATE\ninline std::string json_parse(const std::string &s, const std::string &key,\n                              const int index) {\n  return detail::json_parse(s, key, index);\n}\n\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_JSON_HH\n"
  },
  {
    "path": "core/include/webview/macros.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_MACROS_H\n#define WEBVIEW_MACROS_H\n\n/**\n * Used to specify function linkage such as extern, inline, etc.\n *\n * When @c WEBVIEW_API is not already defined, the defaults are as follows:\n *\n * - @c inline when compiling C++ code.\n * - @c extern when compiling C code.\n *\n * The following macros can be used to automatically set an appropriate\n * value for @c WEBVIEW_API:\n *\n * - Define @c WEBVIEW_BUILD_SHARED when building a shared library.\n * - Define @c WEBVIEW_SHARED when using a shared library.\n * - Define @c WEBVIEW_STATIC when building or using a static library.\n */\n#ifndef WEBVIEW_API\n#if defined(WEBVIEW_SHARED) || defined(WEBVIEW_BUILD_SHARED)\n#if defined(_WIN32) || defined(__CYGWIN__)\n#if defined(WEBVIEW_BUILD_SHARED)\n#define WEBVIEW_API __declspec(dllexport)\n#else\n#define WEBVIEW_API __declspec(dllimport)\n#endif\n#else\n#define WEBVIEW_API __attribute__((visibility(\"default\")))\n#endif\n#elif !defined(WEBVIEW_STATIC) && defined(__cplusplus)\n#define WEBVIEW_API inline\n#else\n#define WEBVIEW_API extern\n#endif\n#endif\n\n/// @name Used internally\n/// @{\n\n/// Utility macro for stringifying a macro argument.\n#define WEBVIEW_STRINGIFY(x) #x\n\n/// Utility macro for stringifying the result of a macro argument expansion.\n#define WEBVIEW_EXPAND_AND_STRINGIFY(x) WEBVIEW_STRINGIFY(x)\n\n/// @}\n\n/// @brief Evaluates to @c TRUE for error codes indicating success or\n///        additional information.\n#define WEBVIEW_SUCCEEDED(error) ((int)(error) >= 0)\n\n/// Evaluates to @c TRUE if the given error code indicates failure.\n#define WEBVIEW_FAILED(error) ((int)(error) < 0)\n\n#ifdef __cplusplus\n#ifndef WEBVIEW_HEADER\n\n#if defined(__APPLE__)\n#define WEBVIEW_PLATFORM_DARWIN\n#elif defined(__unix__)\n#define WEBVIEW_PLATFORM_LINUX\n#elif defined(_WIN32)\n#define WEBVIEW_PLATFORM_WINDOWS\n#else\n#error \"Unable to detect current platform\"\n#endif\n\n#if !defined(WEBVIEW_GTK) && !defined(WEBVIEW_COCOA) && !defined(WEBVIEW_EDGE)\n#if defined(WEBVIEW_PLATFORM_DARWIN)\n#define WEBVIEW_COCOA\n#elif defined(WEBVIEW_PLATFORM_LINUX)\n#define WEBVIEW_GTK\n#elif defined(WEBVIEW_PLATFORM_WINDOWS)\n#define WEBVIEW_EDGE\n#else\n#error \"please, specify webview backend\"\n#endif\n#endif\n\n#ifndef WEBVIEW_DEPRECATED\n#if __cplusplus >= 201402L\n#define WEBVIEW_DEPRECATED(reason) [[deprecated(reason)]]\n#elif defined(_MSC_VER)\n#define WEBVIEW_DEPRECATED(reason) __declspec(deprecated(reason))\n#else\n#define WEBVIEW_DEPRECATED(reason) __attribute__((deprecated(reason)))\n#endif\n#endif\n\n#ifndef WEBVIEW_DEPRECATED_PRIVATE\n#define WEBVIEW_DEPRECATED_PRIVATE                                             \\\n  WEBVIEW_DEPRECATED(\"Private API should not be used\")\n#endif\n\n#endif // WEBVIEW_HEADER\n#endif // __cplusplus\n\n#endif // WEBVIEW_MACROS_H\n"
  },
  {
    "path": "core/include/webview/types.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_TYPES_H\n#define WEBVIEW_TYPES_H\n\n/// Holds the elements of a MAJOR.MINOR.PATCH version number.\ntypedef struct {\n  /// Major version.\n  unsigned int major;\n  /// Minor version.\n  unsigned int minor;\n  /// Patch version.\n  unsigned int patch;\n} webview_version_t;\n\n/// Holds the library's version information.\ntypedef struct {\n  /// The elements of the version number.\n  webview_version_t version;\n  /// SemVer 2.0.0 version number in MAJOR.MINOR.PATCH format.\n  char version_number[32];\n  /// SemVer 2.0.0 pre-release labels prefixed with \"-\" if specified, otherwise\n  /// an empty string.\n  char pre_release[48];\n  /// SemVer 2.0.0 build metadata prefixed with \"+\", otherwise an empty string.\n  char build_metadata[48];\n} webview_version_info_t;\n\n/// Pointer to a webview instance.\ntypedef void *webview_t;\n\n/// Native handle kind. The actual type depends on the backend.\ntypedef enum {\n  /// Top-level window. @c GtkWindow pointer (GTK), @c NSWindow pointer (Cocoa)\n  /// or @c HWND (Win32).\n  WEBVIEW_NATIVE_HANDLE_KIND_UI_WINDOW,\n  /// Browser widget. @c GtkWidget pointer (GTK), @c NSView pointer (Cocoa) or\n  /// @c HWND (Win32).\n  WEBVIEW_NATIVE_HANDLE_KIND_UI_WIDGET,\n  /// Browser controller. @c WebKitWebView pointer (WebKitGTK), @c WKWebView\n  /// pointer (Cocoa/WebKit) or @c ICoreWebView2Controller pointer\n  /// (Win32/WebView2).\n  WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER\n} webview_native_handle_kind_t;\n\n/// Window size hints\ntypedef enum {\n  /// Width and height are default size.\n  WEBVIEW_HINT_NONE,\n  /// Width and height are minimum bounds.\n  WEBVIEW_HINT_MIN,\n  /// Width and height are maximum bounds.\n  WEBVIEW_HINT_MAX,\n  /// Window size can not be changed by a user.\n  WEBVIEW_HINT_FIXED\n} webview_hint_t;\n\n#endif // WEBVIEW_TYPES_H\n"
  },
  {
    "path": "core/include/webview/types.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_TYPES_HH\n#define WEBVIEW_TYPES_HH\n\n#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n\n#include \"detail/basic_result.hh\"\n#include \"errors.hh\"\n\n#include <functional>\n\nnamespace webview {\n\nusing dispatch_fn_t = std::function<void()>;\n\ntemplate <typename T>\nusing result = detail::basic_result<T, error_info, exception>;\n\nusing noresult = detail::basic_result<void, error_info, exception>;\n\n} // namespace webview\n\n#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)\n#endif // WEBVIEW_TYPES_HH\n"
  },
  {
    "path": "core/include/webview/version.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_VERSION_H\n#define WEBVIEW_VERSION_H\n\n#include \"macros.h\"\n\n/// @name Version\n/// @{\n\n#ifndef WEBVIEW_VERSION_MAJOR\n/// The current library major version.\n#define WEBVIEW_VERSION_MAJOR 0\n#endif\n\n#ifndef WEBVIEW_VERSION_MINOR\n/// The current library minor version.\n#define WEBVIEW_VERSION_MINOR 12\n#endif\n\n#ifndef WEBVIEW_VERSION_PATCH\n/// The current library patch version.\n#define WEBVIEW_VERSION_PATCH 0\n#endif\n\n#ifndef WEBVIEW_VERSION_PRE_RELEASE\n/// SemVer 2.0.0 pre-release labels prefixed with \"-\".\n#define WEBVIEW_VERSION_PRE_RELEASE \"\"\n#endif\n\n#ifndef WEBVIEW_VERSION_BUILD_METADATA\n/// SemVer 2.0.0 build metadata prefixed with \"+\".\n#define WEBVIEW_VERSION_BUILD_METADATA \"\"\n#endif\n\n/// SemVer 2.0.0 version number in MAJOR.MINOR.PATCH format.\n#define WEBVIEW_VERSION_NUMBER                                                 \\\n  WEBVIEW_EXPAND_AND_STRINGIFY(WEBVIEW_VERSION_MAJOR)                          \\\n  \".\" WEBVIEW_EXPAND_AND_STRINGIFY(                                            \\\n      WEBVIEW_VERSION_MINOR) \".\" WEBVIEW_EXPAND_AND_STRINGIFY(WEBVIEW_VERSION_PATCH)\n\n/// @}\n\n#endif // WEBVIEW_VERSION_H\n"
  },
  {
    "path": "core/include/webview/webview.h",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2017 Serge Zaitsev\n * Copyright (c) 2022 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_H\n#define WEBVIEW_H\n\n#include \"api.h\"\n#include \"c_api_impl.hh\"\n\n#endif // WEBVIEW_H\n"
  },
  {
    "path": "core/include/webview.h",
    "content": "/**\n * @file webview.h\n *\n * @deprecated This header file is deprecated. Use `webview/webview.h` instead.\n *\n * This file is provided for backward-compatibility with existing code\n * such as `#include \"webview.h\"`.\n */\n\n#ifndef WEBVIEW_ROOT_H\n#define WEBVIEW_ROOT_H\n\n#include \"webview/webview.h\"\n\n#endif // WEBVIEW_ROOT_H\n"
  },
  {
    "path": "core/src/webview.cc",
    "content": "#include \"webview/webview.h\"\n"
  },
  {
    "path": "core/tests/CMakeLists.txt",
    "content": "include(${PROJECT_SOURCE_DIR}/test_driver/cmake/discovery.cmake)\n\nif(MSVC)\n    add_compile_options(/utf-8)\nendif()\n\nadd_executable(webview_core_functional_tests)\ntarget_sources(webview_core_functional_tests PRIVATE src/functional_tests.cc)\ntarget_link_libraries(webview_core_functional_tests PRIVATE webview::core webview_test_driver)\nwebview_discover_tests(webview_core_functional_tests\n    TIMEOUT 60\n    TIMEOUT_AFTER_MATCH 300 \"[[slow]]\")\n\nadd_executable(webview_core_unit_tests)\ntarget_sources(webview_core_unit_tests PRIVATE src/unit_tests.cc)\ntarget_link_libraries(webview_core_unit_tests PRIVATE webview::core webview_test_driver)\nwebview_discover_tests(webview_core_unit_tests\n    TIMEOUT 10)\n"
  },
  {
    "path": "core/tests/src/functional_tests.cc",
    "content": "#include \"webview/test_driver.hh\"\n\n#define WEBVIEW_VERSION_MAJOR 1\n#define WEBVIEW_VERSION_MINOR 2\n#define WEBVIEW_VERSION_PATCH 3\n#define WEBVIEW_VERSION_PRE_RELEASE \"-test\"\n#define WEBVIEW_VERSION_BUILD_METADATA \"+gaabbccd\"\n\n#include \"webview/webview.h\"\n\n#include <cassert>\n#include <cstdint>\n\n// This test should only run on Windows to enable us to perform a controlled\n// \"warm-up\" of MS WebView2 in order to avoid the initial test from\n// occationally timing out in CI.\n#ifdef WEBVIEW_PLATFORM_WINDOWS\n#include <iostream>\n\nTEST_CASE(\"# Warm-up\") {\n  // Signal to the test runner that this may be a slow test.\n  std::cerr << \"[[slow]]\" << std::endl; // NOLINT(performance-avoid-endl)\n  webview::webview w(false, nullptr);\n  w.dispatch([&]() { w.terminate(); });\n  w.run();\n}\n#endif\n\nTEST_CASE(\"Start app loop and terminate it\") {\n  webview::webview w(false, nullptr);\n  w.dispatch([&]() { w.terminate(); });\n  w.run();\n}\n\nvoid cb_assert_arg(webview_t w, void *arg) {\n  REQUIRE(w != nullptr);\n  REQUIRE(memcmp(arg, \"arg\", 3) == 0);\n}\n\nvoid cb_terminate(webview_t w, void *arg) {\n  REQUIRE(arg == nullptr);\n  webview_terminate(w);\n}\n\nTEST_CASE(\"Use C API to create a window, run app and terminate it\") {\n  webview_t w;\n  w = webview_create(false, nullptr);\n  webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);\n  webview_set_title(w, \"Test\");\n  webview_set_html(w, \"set_html ok\");\n  webview_navigate(w, \"data:text/plain,navigate%20ok\");\n  webview_dispatch(w, cb_assert_arg, (void *)\"arg\");\n  webview_dispatch(w, cb_terminate, nullptr);\n  webview_run(w);\n  webview_destroy(w);\n}\n\nTEST_CASE(\"Use C API to test binding and unbinding\") {\n  struct context_t {\n    webview_t w;\n    unsigned int number;\n  } context{};\n  auto test = +[](const char *seq, const char *req, void *arg) {\n    auto increment = +[](const char *seq, const char * /*req*/, void *arg) {\n      auto *context = static_cast<context_t *>(arg);\n      ++context->number;\n      webview_return(context->w, seq, 0, \"\");\n    };\n    auto context = static_cast<context_t *>(arg);\n    std::string req_(req);\n    // Bind and increment number.\n    if (req_ == \"[0]\") {\n      REQUIRE(context->number == 0);\n      webview_bind(context->w, \"increment\", increment, context);\n      webview_eval(context->w,\n                   \"try{window.increment().then(r => window.test(1))\"\n                   \".catch(() => window.test(1,1))}\"\n                   \"catch{window.test(1,1)}\");\n      webview_return(context->w, seq, 0, \"\");\n      return;\n    }\n    // Unbind and make sure that we cannot increment even if we try.\n    if (req_ == \"[1]\") {\n      REQUIRE(context->number == 1);\n      webview_unbind(context->w, \"increment\");\n      webview_eval(context->w,\n                   \"try{window.increment().then(r => window.test(2))\"\n                   \".catch(() => window.test(2,1))}\"\n                   \"catch{window.test(2,1)}\");\n      webview_return(context->w, seq, 0, \"\");\n      return;\n    }\n    // Number should not have changed but we can bind again and change the number.\n    if (req_ == \"[2,1]\") {\n      REQUIRE(context->number == 1);\n      webview_bind(context->w, \"increment\", increment, context);\n      webview_eval(context->w,\n                   \"try{window.increment().then(r => window.test(3))\"\n                   \".catch(() => window.test(3,1))}\"\n                   \"catch{window.test(3,1)}\");\n      webview_return(context->w, seq, 0, \"\");\n      return;\n    }\n    // Finish test.\n    if (req_ == \"[3]\") {\n      REQUIRE(context->number == 2);\n      webview_terminate(context->w);\n      return;\n    }\n    REQUIRE(!\"Should not reach here\");\n  };\n  auto html = \"<script>\\n\"\n              \"  window.test(0);\\n\"\n              \"</script>\";\n  auto w = webview_create(1, nullptr);\n  context.w = w;\n  // Attempting to remove non-existing binding is OK\n  webview_unbind(w, \"test\");\n  webview_bind(w, \"test\", test, &context);\n  // Attempting to bind multiple times only binds once\n  webview_bind(w, \"test\", test, &context);\n  webview_set_html(w, html);\n  webview_run(w);\n}\n\nTEST_CASE(\"Test synchronous binding and unbinding\") {\n  auto make_call_js = [](unsigned int result) {\n    std::string js;\n    js += \"try{window.increment().then(r => window.test(\";\n    js += std::to_string(result);\n    js += \"))\";\n    js += \".catch(() => window.test(\";\n    js += std::to_string(result);\n    js += \",1))}catch{window.test(\";\n    js += std::to_string(result);\n    js += \",1)}\";\n    return js;\n  };\n  unsigned int number = 0;\n  webview::webview w(false, nullptr);\n  auto test = [&](const std::string &req) -> std::string {\n    auto increment = [&](const std::string & /*req*/) -> std::string {\n      ++number;\n      return \"\";\n    };\n    // Bind and increment number.\n    if (req == \"[0]\") {\n      REQUIRE(number == 0);\n      w.bind(\"increment\", increment);\n      w.eval(make_call_js(1));\n      return \"\";\n    }\n    // Unbind and make sure that we cannot increment even if we try.\n    if (req == \"[1]\") {\n      REQUIRE(number == 1);\n      w.unbind(\"increment\");\n      w.eval(make_call_js(2));\n      return \"\";\n    }\n    // We should have gotten an error on the JS side.\n    // Number should not have changed but we can bind again and change the number.\n    if (req == \"[2,1]\") {\n      REQUIRE(number == 1);\n      w.bind(\"increment\", increment);\n      w.eval(make_call_js(3));\n      return \"\";\n    }\n    // Finish test.\n    if (req == \"[3]\") {\n      REQUIRE(number == 2);\n      w.terminate();\n      return \"\";\n    }\n    REQUIRE(!\"Should not reach here\");\n    return \"\";\n  };\n  auto html = \"<script>\\n\"\n              \"  window.test(0);\\n\"\n              \"</script>\";\n  // Attempting to remove non-existing binding is OK\n  w.unbind(\"test\");\n  w.bind(\"test\", test);\n  // Attempting to bind multiple times only binds once\n  w.bind(\"test\", test);\n  w.set_html(html);\n  w.run();\n}\n\nTEST_CASE(\"The string returned from a binding call must be JSON\") {\n  constexpr auto html =\n      R\"html(<script>\n  try {\n    window.loadData()\n      .then(() => window.endTest(0))\n      .catch(() => window.endTest(1));\n  } catch {\n    window.endTest(2);\n  }\n</script>)html\";\n\n  webview::webview w(true, nullptr);\n\n  w.bind(\"loadData\", [](const std::string & /*req*/) -> std::string {\n    return \"\\\"hello\\\"\";\n  });\n\n  w.bind(\"endTest\", [&](const std::string &req) -> std::string {\n    REQUIRE(req != \"[2]\");\n    REQUIRE(req != \"[1]\");\n    REQUIRE(req == \"[0]\");\n    w.terminate();\n    return \"\";\n  });\n\n  w.set_html(html);\n  w.run();\n}\n\nTEST_CASE(\"The string returned of a binding call must not be JS\") {\n  constexpr const auto html =\n      R\"html(<script>\n  try {\n    window.loadData()\n      .then(() => window.endTest(0))\n      .catch(() => window.endTest(1));\n  } catch {\n    window.endTest(2);\n  }\n</script>)html\";\n\n  webview::webview w(true, nullptr);\n\n  w.bind(\"loadData\", [](const std::string & /*req*/) -> std::string {\n    // Try to load malicious JS code\n    return \"(()=>{document.body.innerHTML='gotcha';return 'hello';})()\";\n  });\n\n  w.bind(\"endTest\", [&](const std::string &req) -> std::string {\n    REQUIRE(req != \"[0]\");\n    REQUIRE(req != \"[2]\");\n    REQUIRE(req == \"[1]\");\n    w.terminate();\n    return \"\";\n  });\n\n  w.set_html(html);\n  w.run();\n}\n\nTEST_CASE(\"webview_version()\") {\n  auto vi = webview_version();\n  REQUIRE(vi);\n  REQUIRE(vi->version.major == 1);\n  REQUIRE(vi->version.minor == 2);\n  REQUIRE(vi->version.patch == 3);\n  REQUIRE(std::string(vi->version_number) == \"1.2.3\");\n  REQUIRE(std::string(vi->pre_release) == \"-test\");\n  REQUIRE(std::string(vi->build_metadata) == \"+gaabbccd\");\n  // The function should return the same pointer when called again.\n  REQUIRE(webview_version() == vi);\n}\n\nstruct test_webview : webview::browser_engine {\n  using cb_t = std::function<void(test_webview *, int, const std::string &)>;\n  test_webview(cb_t cb) : webview::browser_engine(true, nullptr), m_cb(cb) {}\n  void on_message(const std::string &msg) override { m_cb(this, i++, msg); }\n  int i = 0;\n  cb_t m_cb;\n};\n\nTEST_CASE(\"Ensure that JS code can call native code and vice versa\") {\n  test_webview browser([](test_webview *w, int i, const std::string &msg) {\n    switch (i) {\n    case 0:\n      REQUIRE(msg == \"loaded\");\n      w->eval(\"window.__webview__.post('exiting ' + window.x)\");\n      break;\n    case 1:\n      REQUIRE(msg == \"exiting 42\");\n      w->terminate();\n      break;\n    default:\n      REQUIRE(0);\n    }\n  });\n  browser.init(R\"(\n    window.x = 42;\n    window.onload = () => {\n      window.__webview__.post('loaded');\n    };\n  )\");\n  browser.navigate(\"data:text/html,%3Chtml%3Ehello%3C%2Fhtml%3E\");\n  browser.run();\n}\n\n#define ASSERT_WEBVIEW_FAILED(expr) REQUIRE(WEBVIEW_FAILED(expr))\n\nTEST_CASE(\"Bad C API usage without crash\") {\n  webview_t w{};\n  REQUIRE(webview_get_window(w) == nullptr);\n  REQUIRE(webview_get_native_handle(w, WEBVIEW_NATIVE_HANDLE_KIND_UI_WINDOW) ==\n          nullptr);\n  ASSERT_WEBVIEW_FAILED(webview_set_size(w, 0, 0, WEBVIEW_HINT_NONE));\n  ASSERT_WEBVIEW_FAILED(webview_navigate(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_set_title(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_set_html(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_init(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_eval(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_bind(w, nullptr, nullptr, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_unbind(w, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_return(w, nullptr, 0, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_dispatch(w, nullptr, nullptr));\n  ASSERT_WEBVIEW_FAILED(webview_terminate(w));\n  ASSERT_WEBVIEW_FAILED(webview_run(w));\n  ASSERT_WEBVIEW_FAILED(webview_destroy(w));\n}\n"
  },
  {
    "path": "core/tests/src/unit_tests.cc",
    "content": "#include \"webview/test_driver.hh\"\n#include \"webview/webview.h\"\n\nTEST_CASE(\"Ensure that JSON parsing works\") {\n  auto J = webview::detail::json_parse;\n  // Valid input with expected output\n  REQUIRE(J(R\"({\"foo\":\"bar\"})\", \"foo\", -1) == \"bar\");\n  REQUIRE(J(R\"({\"foo\":\"\"})\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({\"foo\":{}\")\", \"foo\", -1) == \"{}\");\n  REQUIRE(J(R\"({\"foo\": {\"bar\": 1}})\", \"foo\", -1) == R\"({\"bar\": 1})\");\n  REQUIRE(J(R\"([\"foo\", \"bar\", \"baz\"])\", \"\", 0) == \"foo\");\n  REQUIRE(J(R\"([\"foo\", \"bar\", \"baz\"])\", \"\", 2) == \"baz\");\n  // Valid UTF-8 with expected output\n  REQUIRE(J(R\"({\"フー\":\"バー\"})\", \"フー\", -1) == \"バー\");\n  REQUIRE(J(R\"([\"フー\", \"バー\", \"バズ\"])\", \"\", 2) == \"バズ\");\n  // Invalid input with valid output - should probably fail\n  REQUIRE(J(R\"({\"foo\":\"bar\")\", \"foo\", -1) == \"bar\");\n  // Valid input with other invalid parameters - should fail\n  REQUIRE(J(R\"([])\", \"\", 0).empty());\n  REQUIRE(J(R\"({})\", \"foo\", -1).empty());\n  REQUIRE(J(R\"([\"foo\", \"bar\", \"baz\"])\", \"\", -1).empty());\n  REQUIRE(J(R\"([\"foo\"])\", \"\", 1234).empty());\n  REQUIRE(J(R\"([\"foo\"])\", \"\", -1234).empty());\n  // Invalid input - should fail\n  REQUIRE(J(\"\", \"\", 0).empty());\n  REQUIRE(J(\"\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({\"foo\":\")\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({\"foo\":{)\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({\"foo\":{\")\", \"foo\", -1).empty());\n  REQUIRE(J(R\"(}\")\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({}}\")\", \"foo\", -1).empty());\n  REQUIRE(J(R\"(\"foo)\", \"foo\", -1).empty());\n  REQUIRE(J(R\"(foo)\", \"foo\", -1).empty());\n  REQUIRE(J(R\"({{[[\"\"foo\"\"]]}})\", \"\", 1234).empty());\n  REQUIRE(J(\"bad\", \"\", 0).empty());\n  REQUIRE(J(\"bad\", \"foo\", -1).empty());\n}\n\nTEST_CASE(\"Ensure that JSON escaping works\") {\n  using webview::detail::json_escape;\n\n  // Simple case without need for escaping. Quotes added by default.\n  REQUIRE(json_escape(\"hello\") == \"\\\"hello\\\"\");\n  // Simple case without need for escaping. Quotes explicitly not added.\n  REQUIRE(json_escape(\"hello\", false) == \"hello\");\n  // Empty input should return empty output.\n  REQUIRE(json_escape(\"\", false).empty());\n  // '\"' and '\\' should be escaped.\n  REQUIRE(json_escape(\"\\\"\", false) == \"\\\\\\\"\");\n  REQUIRE(json_escape(\"\\\\\", false) == \"\\\\\\\\\");\n  // Commonly-used characters that should be escaped.\n  REQUIRE(json_escape(\"\\b\\f\\n\\r\\t\", false) == \"\\\\b\\\\f\\\\n\\\\r\\\\t\");\n  // ASCII control characters should be escaped.\n  REQUIRE(json_escape(std::string{\"\\0\\x1f\", 2}, false) == \"\\\\u0000\\\\u001f\");\n  // ASCII printable characters (even DEL) shouldn't be escaped.\n  REQUIRE(json_escape(\"\\x20\\x7e\\x7f\", false) == \"\\x20\\x7e\\x7f\");\n  // Valid UTF-8.\n  REQUIRE(json_escape(\"\\u2328\", false) == \"\\u2328\");\n  REQUIRE(json_escape(\"フーバー\", false) == \"フーバー\");\n  // Replacement character for invalid characters.\n  REQUIRE(json_escape(\"�\", false) == \"�\");\n  // Invalid characters should be replaced with '�' but we just leave them as-is.\n  REQUIRE(json_escape(\"\\x80\\x9f\\xa0\\xff\", false) == \"\\x80\\x9f\\xa0\\xff\");\n  // JS code should not be executed (eval).\n  auto expected_gotcha = R\"js(alert(\\\"gotcha\\\"))js\";\n  REQUIRE(json_escape(R\"(alert(\"gotcha\"))\", false) == expected_gotcha);\n}\n\nTEST_CASE(\"optional class\") {\n  using namespace webview::detail;\n\n  REQUIRE(!optional<int>{}.has_value());\n  REQUIRE(optional<int>{1}.has_value());\n  REQUIRE(optional<int>{1}.get() == 1);\n\n  REQUIRE_THROW(bad_access, [] { optional<int>{}.get(); });\n\n  REQUIRE(!optional<int>{optional<int>{}}.has_value());\n  REQUIRE(optional<int>{optional<int>{1}}.has_value());\n  REQUIRE(optional<int>{optional<int>{1}}.get() == 1);\n}\n\nTEST_CASE(\"result class\") {\n  using namespace webview::detail;\n  using namespace webview;\n\n  REQUIRE(result<int>{}.has_value());\n  REQUIRE(result<int>{}.value() == 0);\n  REQUIRE(result<int>{1}.has_value());\n  REQUIRE(result<int>{1}.value() == 1);\n  REQUIRE(!result<int>{}.has_error());\n  REQUIRE(!result<int>{1}.has_error());\n  REQUIRE(result<int>{}.ok());\n  REQUIRE(result<int>{1}.ok());\n  REQUIRE(!result<int>{error_info{}}.ok());\n  REQUIRE(!result<int>{error_info{}}.has_value());\n  REQUIRE(result<int>{error_info{}}.has_error());\n\n  auto result_with_error = result<int>{\n      error_info{WEBVIEW_ERROR_INVALID_ARGUMENT, \"invalid argument\"}};\n  REQUIRE(result_with_error.error().code() == WEBVIEW_ERROR_INVALID_ARGUMENT);\n  REQUIRE(result_with_error.error().message() == \"invalid argument\");\n\n  REQUIRE_THROW(bad_access, [] { result<int>{}.error(); });\n}\n\nTEST_CASE(\"noresult class\") {\n  using namespace webview::detail;\n  using namespace webview;\n\n  REQUIRE(!noresult{}.has_error());\n  REQUIRE(noresult{}.ok());\n  REQUIRE(!noresult{error_info{}}.ok());\n  REQUIRE(noresult{error_info{}}.has_error());\n\n  auto result_with_error =\n      noresult{error_info{WEBVIEW_ERROR_INVALID_ARGUMENT, \"invalid argument\"}};\n  REQUIRE(result_with_error.error().code() == WEBVIEW_ERROR_INVALID_ARGUMENT);\n  REQUIRE(result_with_error.error().message() == \"invalid argument\");\n\n  REQUIRE_THROW(bad_access, [] { noresult{}.error(); });\n}\n\n#if _WIN32\nTEST_CASE(\"Ensure that version number parsing works on Windows\") {\n  using namespace webview::detail;\n  auto v = parse_version(\"\");\n  REQUIRE(v.size() == 4);\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"1\");\n  REQUIRE(v[0] == 1 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"0.2\");\n  REQUIRE(v[0] == 0 && v[1] == 2 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"0.0.3\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 3 && v[3] == 0);\n  v = parse_version(\"0.0.0.4\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 4);\n  v = parse_version(\"1.2.3.4.5\");\n  REQUIRE(v.size() == 4);\n  REQUIRE(v[0] == 1 && v[1] == 2 && v[2] == 3 && v[3] == 4);\n  v = parse_version(\"1.2.3.4.5.6\");\n  REQUIRE(v[0] == 1 && v[1] == 2 && v[2] == 3 && v[3] == 4);\n  v = parse_version(\"11.22.33.44\");\n  REQUIRE(v[0] == 11 && v[1] == 22 && v[2] == 33 && v[3] == 44);\n  v = parse_version(\"0.0.0.0\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"-1.-2.-3.-4\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"a.b.c.d\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n  v = parse_version(\"...\");\n  REQUIRE(v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 0);\n}\n\nTEST_CASE(\"Ensure that narrow/wide string conversion works on Windows\") {\n  using namespace webview::detail;\n  REQUIRE(widen_string(\"\").empty());\n  REQUIRE(narrow_string(L\"\").empty());\n  REQUIRE(widen_string(\"foo\") == L\"foo\");\n  REQUIRE(narrow_string(L\"foo\") == \"foo\");\n  REQUIRE(widen_string(\"フー\") == L\"フー\");\n  REQUIRE(narrow_string(L\"フー\") == \"フー\");\n  REQUIRE(widen_string(\"æøå\") == L\"æøå\");\n  REQUIRE(narrow_string(L\"æøå\") == \"æøå\");\n  // Unicode number for the smiley face below: U+1F600\n  REQUIRE(widen_string(\"😀\") == L\"😀\");\n  REQUIRE(narrow_string(L\"😀\") == \"😀\");\n  // Ensure that elements of wide string are correct\n  {\n    auto s = widen_string(\"😀\");\n    REQUIRE(s.size() == 2);\n    REQUIRE(static_cast<std::uint16_t>(s[0]) == 0xD83D);\n    REQUIRE(static_cast<std::uint16_t>(s[1]) == 0xDE00);\n  }\n  // Ensure that elements of narrow string are correct\n  {\n    auto s = narrow_string(L\"😀\");\n    REQUIRE(s.size() == 4);\n    REQUIRE(static_cast<std::uint8_t>(s[0]) == 0xf0);\n    REQUIRE(static_cast<std::uint8_t>(s[1]) == 0x9f);\n    REQUIRE(static_cast<std::uint8_t>(s[2]) == 0x98);\n    REQUIRE(static_cast<std::uint8_t>(s[3]) == 0x80);\n  }\n  // Null-characters must also be converted\n  REQUIRE(widen_string(std::string(2, '\\0')) == std::wstring(2, L'\\0'));\n  REQUIRE(narrow_string(std::wstring(2, L'\\0')) == std::string(2, '\\0'));\n}\n#endif\n"
  },
  {
    "path": "docs/CMakeLists.txt",
    "content": "add_subdirectory(api)\n\nadd_custom_target(webview_docs DEPENDS webview_api_docs)\n"
  },
  {
    "path": "docs/api/CMakeLists.txt",
    "content": "webview_find_doxygen(${WEBVIEW_IS_CI})\n\nif(NOT Doxygen_FOUND)\n    message(WARNING \"Skipping docs as Doxygen was not found\")\n    return()\nendif()\n\n# We can set this to \"-$<CONFIG>\" if we need per-config documentation\nset(CONFIG_SUFFIX \"\")\nset(DOXYFILE_HAVE_DOT YES)\nset(DOXYFILE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/output${CONFIG_SUFFIX}\")\nset(DOXYFILE_CLANG_DATABASE_PATH \"${PROJECT_BINARY_DIR}\")\nset(DOXYFILE_USE_MDFILE_AS_MAINPAGE \"${PROJECT_SOURCE_DIR}/README.md\")\n\nget_target_property(CORE_SOURCE_DIR webview::core SOURCE_DIR)\nset(DOXYFILE_INPUT \"${CORE_SOURCE_DIR}/include\")\n\nset(RUN_DOXYGEN_FILE \"${CMAKE_CURRENT_BINARY_DIR}/run_doxygen${CONFIG_SUFFIX}.cmake\")\n\nfile(GLOB_RECURSE DOCS_INPUT_FILES CONFIGURE_DEPENDS \"${DOXYFILE_INPUT}/**\")\n\nfile(GENERATE\n    OUTPUT \"${RUN_DOXYGEN_FILE}\"\n    CONTENT \"set(DOXYGEN_EXECUTABLE \\\"${DOXYGEN_EXECUTABLE}\\\")\\n\\\nset(PROJECT_NAME \\\"${PROJECT_NAME}\\\")\\n\\\nset(PROJECT_VERSION \\\"${PROJECT_VERSION}\\\")\\n\\\nset(PROJECT_DESCRIPTION \\\"${PROJECT_DESCRIPTION}\\\")\\n\\\nset(DOXYFILE_HAVE_DOT \\\"${DOXYFILE_HAVE_DOT}\\\")\\n\\\nset(DOXYFILE_OUTPUT_DIRECTORY \\\"${DOXYFILE_OUTPUT_DIRECTORY}\\\")\\n\\\nset(DOXYFILE_INPUT \\\"${DOXYFILE_INPUT}\\\")\\n\\\nset(DOXYFILE_USE_MDFILE_AS_MAINPAGE \\\"${DOXYFILE_USE_MDFILE_AS_MAINPAGE}\\\")\\n\\\nset(DOXYFILE_CLANG_DATABASE_PATH \\\"${DOXYFILE_CLANG_DATABASE_PATH}\\\")\\n\\\nconfigure_file(\\\"${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in\\\" \\\"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile${CONFIG_SUFFIX}\\\" @ONLY)\\n\\\nexecute_process(COMMAND \\\"${DOXYGEN_EXECUTABLE}\\\" \\\"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile${CONFIG_SUFFIX}\\\")\"\n)\n\nset(API_DOCS_STAMP_FILE \"${CMAKE_CURRENT_BINARY_DIR}/webview_api_docs${CONFIG_SUFFIX}.stamp\")\nadd_custom_command(\n    OUTPUT \"${API_DOCS_STAMP_FILE}\"\n    COMMAND \"${CMAKE_COMMAND}\" -E touch \"${API_DOCS_STAMP_FILE}\"\n    COMMAND \"${CMAKE_COMMAND}\" -E rm -rf \"${DOXYFILE_OUTPUT_DIRECTORY}\"\n    COMMAND \"${CMAKE_COMMAND}\" -P \"${RUN_DOXYGEN_FILE}\"\n    DEPENDS ${DOCS_INPUT_FILES} \"${RUN_DOXYGEN_FILE}\"\n    VERBATIM)\n\nadd_custom_target(webview_api_docs ALL DEPENDS \"${API_DOCS_STAMP_FILE}\")\n\nif(WEBVIEW_INSTALL_DOCS)\n    install(DIRECTORY \"${DOXYFILE_OUTPUT_DIRECTORY}/html\"\n        DESTINATION \"${CMAKE_INSTALL_DOCDIR}\"\n        COMPONENT webview_api_docs)\nendif()\n"
  },
  {
    "path": "docs/api/Doxyfile.in",
    "content": "# Doxyfile 1.9.1\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the configuration\n# file that follow. The default is UTF-8 which is also the encoding used for all\n# text before the first occurrence of this tag. Doxygen uses libiconv (or the\n# iconv built into libc) for the transcoding. See\n# https://www.gnu.org/software/libiconv/ for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = \"@PROJECT_NAME@\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         = \"@PROJECT_VERSION@\"\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"@PROJECT_DESCRIPTION@\"\n\n# With the PROJECT_LOGO tag one can specify a logo or an icon that is included\n# in the documentation. The maximum height of the logo should not exceed 55\n# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy\n# the logo to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = \"@DOXYFILE_OUTPUT_DIRECTORY@\"\n\n# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII\n# characters to appear in the names of generated files. If set to NO, non-ASCII\n# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode\n# U+3044.\n# The default value is: NO.\n\nALLOW_UNICODE_NAMES    = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all generated output in the proper direction.\n# Possible values are: None, LTR, RTL and Context.\n# The default value is: None.\n\nOUTPUT_TEXT_DIRECTION  = None\n\n# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        = \"@DOXYFILE_INPUT@\"\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = NO\n\n# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line\n# such as\n# /***************\n# as being the beginning of a Javadoc-style comment \"banner\". If set to NO, the\n# Javadoc-style will behave just like regular comments and it will not be\n# interpreted by doxygen.\n# The default value is: NO.\n\nJAVADOC_BANNER         = NO\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# By default Python docstrings are displayed as preformatted text and doxygen's\n# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the\n# doxygen's special commands can be used and the contents of the docstring\n# documentation blocks is shown as doxygen documentation.\n# The default value is: YES.\n\nPYTHON_DOCSTRING       = YES\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new\n# page for each member. If set to NO, the documentation of a member will be part\n# of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines (in the resulting output). You can put ^^ in the value part of an\n# alias to insert a newline as if a physical newline was in the original file.\n# When you need a literal { or } or , in the value part of an alias you have to\n# escape them by means of a backslash (\\), this can lead to conflicts with the\n# commands \\{ and \\} for these it is advised to use the version @{ and @} or use\n# a double escape (\\\\{ and \\\\})\n\nALIASES                =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice\n# sources only. Doxygen will then generate output that is more tailored for that\n# language. For instance, namespaces will be presented as modules, types will be\n# separated into more groups, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_SLICE  = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,\n# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,\n# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:\n# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser\n# tries to guess whether the code is fixed or free formatted code, this is the\n# default for Fortran type files). For instance to make doxygen treat .inc files\n# as Fortran files (default is PHP), and .f files as C (default is Fortran),\n# use: inc=Fortran f=C.\n#\n# Note: For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen. When specifying no_extension you should add\n# * to the FILE_PATTERNS.\n#\n# Note see also the list of default file extension mappings.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See https://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up\n# to that level are automatically included in the table of contents, even if\n# they do not have an id attribute.\n# Note: This feature currently applies only to Markdown headings.\n# Minimum value: 0, maximum value: 99, default value: 5.\n# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.\n\nTOC_INCLUDE_HEADINGS   = 5\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by putting a % sign in front of the word or\n# globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# If one adds a struct or class to a group and this option is enabled, then also\n# any nested class or struct is added to the same group. By default this option\n# is disabled and one has to add nested compounds explicitly via \\ingroup.\n# The default value is: NO.\n\nGROUP_NESTED_COMPOUNDS = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use\n# during processing. When set to 0 doxygen will based this on the number of\n# cores available in the system. You can set it explicitly to a value larger\n# than 0 to get more control over the balance between CPU load and processing\n# speed. At this moment only the input processing can be done using multiple\n# threads. Since this is still an experimental feature the default is set to 1,\n# which efficively disables parallel processing. Please report any issues you\n# encounter. Generating dot graphs in parallel is controlled by the\n# DOT_NUM_THREADS setting.\n# Minimum value: 0, maximum value: 32, default value: 1.\n\nNUM_PROC_THREADS       = 1\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual\n# methods of a class will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIV_VIRTUAL   = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO,\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = NO\n\n# This flag is only useful for Objective-C code. If set to YES, local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO, only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If this flag is set to YES, the name of an unnamed parameter in a declaration\n# will be determined by the corresponding definition. By default unnamed\n# parameters remain unnamed in the output.\n# The default value is: YES.\n\nRESOLVE_UNNAMED_PARAMS = YES\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO, these classes will be included in the various overviews. This option\n# has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# declarations. If set to NO, these declarations will be included in the\n# documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO, these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# With the correct setting of option CASE_SENSE_NAMES doxygen will better be\n# able to match the capabilities of the underlying filesystem. In case the\n# filesystem is case sensitive (i.e. it supports files in the same directory\n# whose names only differ in casing), the option must be set to YES to properly\n# deal with such files in case they appear in the input. For filesystems that\n# are not case sensitive the option should be be set to NO to properly deal with\n# output files written for symbols that only differ in casing, such as for two\n# classes, one named CLASS and the other named Class, and to also support\n# references to files without having to specify the exact matching casing. On\n# Windows (including Cygwin) and MacOS, users should typically set this option\n# to NO, whereas on Linux or other Unix flavors it should typically be set to\n# YES.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES, the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will\n# append additional text to a page's title, such as Class Reference. If set to\n# YES the compound reference will be hidden.\n# The default value is: NO.\n\nHIDE_COMPOUND_REFERENCE= NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = NO\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo\n# list. This list is created by putting \\todo commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test\n# list. This list is created by putting \\test commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES, the\n# list will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            =\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. See also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO, doxygen will only warn about wrong or incomplete\n# parameter documentation, but not about the absence of documentation. If\n# EXTRACT_ALL is set to YES then this flag will automatically be disabled.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when\n# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS\n# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but\n# at the end of the doxygen process doxygen will return with a non-zero status.\n# Possible values are: NO, YES and FAIL_ON_WARNINGS.\n# The default value is: NO.\n\nWARN_AS_ERROR          = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = \"@DOXYFILE_INPUT@\" \\\n                         \"@DOXYFILE_USE_MDFILE_AS_MAINPAGE@\"\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see:\n# https://www.gnu.org/software/libiconv/) for the list of possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# read by doxygen.\n#\n# Note the list of default checked file patterns might differ from the list of\n# default file extension mappings.\n#\n# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,\n# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,\n# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,\n# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),\n# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,\n# *.ucf, *.qsf and *.ice.\n\nFILE_PATTERNS          = *.c \\\n                         *.cc \\\n                         *.cpp \\\n                         *.cxx \\\n                         *.h \\\n                         *.hh \\\n                         *.hpp \\\n                         *.hxx\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       = */detail/*\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        = *::detail\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             =\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE = \"@DOXYFILE_USE_MDFILE_AS_MAINPAGE@\"\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# entity all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see https://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the\n# clang parser (see:\n# http://clang.llvm.org/) for more accurate parsing at the cost of reduced\n# performance. This can be particularly helpful with template rich C++ code for\n# which doxygen's built-in parser lacks the necessary type information.\n# Note: The availability of this option depends on whether or not doxygen was\n# generated with the -Duse_libclang=ON option for CMake.\n# The default value is: NO.\n\nCLANG_ASSISTED_PARSING = NO\n\n# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to\n# YES then doxygen will add the directory of each input to the include path.\n# The default value is: YES.\n\nCLANG_ADD_INC_PATHS    = YES\n\n# If clang assisted parsing is enabled you can provide the compiler with command\n# line options that you would normally use when invoking the compiler. Note that\n# the include paths will already be set by doxygen for the files and directories\n# specified with INPUT and INCLUDE_PATH.\n# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.\n\nCLANG_OPTIONS          =\n\n# If clang assisted parsing is enabled you can provide the clang parser with the\n# path to the directory containing a file called compile_commands.json. This\n# file is the compilation database (see:\n# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the\n# options used when the source files were built. This is equivalent to\n# specifying the -p option to a clang tool, such as clang-check. These options\n# will then be passed to the parser. Any options specified with CLANG_OPTIONS\n# will be added as well.\n# Note: The availability of this option depends on whether or not doxygen was\n# generated with the -Duse_libclang=ON option for CMake.\n\nCLANG_DATABASE_PATH    = \"@DOXYFILE_CLANG_DATABASE_PATH@\"\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            =\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            =\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        =\n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# cascading style sheets that are included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefore more robust against future updates.\n# Doxygen will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list). For an example see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  =\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       =\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the style sheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# https://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to YES can help to show when doxygen was last run and thus if the\n# documentation is up to date.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML\n# documentation will contain a main index with vertical navigation menus that\n# are dynamically created via JavaScript. If disabled, the navigation index will\n# consists of multiple levels of tabs that are statically embedded in every HTML\n# page. Disable this option to support browsers that do not have JavaScript,\n# like the Qt help browser.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_MENUS     = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see:\n# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To\n# create a documentation set, doxygen will generate a Makefile in the HTML\n# output directory. Running make will produce the docset in that directory and\n# running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy\n# genXcode/_index.html for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see:\n# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler (hhc.exe). If non-empty,\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated\n# (YES) or that it should be included in the main .chm file (NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated\n# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it\n# enables the Previous and Next buttons.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location (absolute path\n# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to\n# run qhelpgenerator on the generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg\n# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see\n# https://inkscape.org) to generate formulas as SVG images instead of PNGs for\n# the HTML output. These images will generally look nicer at scaled resolutions.\n# Possible values are: png (the default) and svg (looks nicer but requires the\n# pdf2svg or inkscape tool).\n# The default value is: png.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FORMULA_FORMAT    = png\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANSPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# The FORMULA_MACROFILE can contain LaTeX \\newcommand and \\renewcommand commands\n# to create new LaTeX commands to be used in formulas as building blocks. See\n# the section \"Including formulas\" for details.\n\nFORMULA_MACROFILE      =\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# https://www.mathjax.org) which uses client side JavaScript for the rendering\n# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from https://www.mathjax.org before deployment.\n# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = https://cdn.jsdelivr.net/npm/mathjax@2\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see:\n# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using JavaScript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see:\n# https://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see:\n# https://xapian.org/). See the section \"External Indexing and Searching\" for\n# details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when not enabling USE_PDFLATEX the default is latex when enabling\n# USE_PDFLATEX the default is pdflatex and when in the later case latex is\n# chosen this is overwritten by pdflatex. For specific output languages the\n# default can have been set differently, this depends on the implementation of\n# the output language.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         =\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# Note: This tag is used in the Makefile / make.bat.\n# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file\n# (.tex).\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to\n# generate index for LaTeX. In case there is no backslash (\\) as first character\n# it will be automatically added in the LaTeX code.\n# Note: This tag is used in the generated output file (.tex).\n# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.\n# The default value is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_MAKEINDEX_CMD    = makeindex\n\n# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. The package can be specified just\n# by its name or with the correct syntax as to be used with the LaTeX\n# \\usepackage command. To get the times font for instance you can specify :\n# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}\n# To use the option intlimits with the amsmath package you can specify:\n# EXTRA_PACKAGES=[intlimits]{amsmath}\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber,\n# $projectbrief, $projectlogo. Doxygen will replace $title with the empty\n# string, for the replacement values of the other commands the user is referred\n# to HTML_HEADER.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer. See\n# LATEX_HEADER for more information on how to generate a default footer and what\n# special commands can be used inside the footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# LaTeX style sheets that are included after the standard style sheets created\n# by doxygen. Using this option one can overrule certain style aspects. Doxygen\n# will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_STYLESHEET =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as\n# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX\n# files. Set this option to YES, to get a higher quality PDF documentation.\n#\n# See also section LATEX_CMD_NAME for selecting the engine.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# https://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_TIMESTAMP        = NO\n\n# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)\n# path from which the emoji images will be read. If a relative path is entered,\n# it will be relative to the LATEX_OUTPUT directory. If left blank the\n# LATEX_OUTPUT directory will be used.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EMOJI_DIRECTORY  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's\n# configuration file, i.e. a series of assignments. You only have to provide\n# replacements, missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's configuration file. A template extensions file can be\n# generated using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code\n# with syntax highlighting in the RTF output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_SOURCE_CODE        = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# The MAN_SUBDIR tag determines the name of the directory created within\n# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by\n# MAN_EXTENSION with the initial . removed.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_SUBDIR             =\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include\n# namespace members in file scope as well, matching the HTML output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_NS_MEMB_FILE_SCOPE = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the\n# program listings (including syntax highlighting and cross-referencing\n# information) to the DOCBOOK output. Note that enabling this will significantly\n# increase the size of the DOCBOOK output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_PROGRAMLISTING = NO\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an\n# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures\n# the structure of the code including all documentation. Note that this feature\n# is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO, the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names\n# in the source code. If set to NO, only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES, the include files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             =\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES, all external class will be listed in\n# the class index. If set to NO, only the inherited external classes will be\n# listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed\n# in the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: YES.\n\nHAVE_DOT               = @DOXYFILE_HAVE_DOT@\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font in the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag UML_LOOK is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and\n# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS\n# tag is set to YES, doxygen will add type and arguments for attributes and\n# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen\n# will not generate fields with class member information in the UML graphs. The\n# class diagrams will look similar to the default class diagrams but using UML\n# notation for the relationships.\n# Possible values are: NO, YES and NONE.\n# The default value is: NO.\n# This tag requires that the tag UML_LOOK is set to YES.\n\nDOT_UML_DETAILS        = NO\n\n# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters\n# to display on a single line. If the actual line length exceeds this threshold\n# significantly it will wrapped across multiple lines. Some heuristics are apply\n# to avoid ugly line breaks.\n# Minimum value: 0, maximum value: 1000, default value: 17.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_WRAP_THRESHOLD     = 17\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command. Disabling a call graph can be\n# accomplished by means of the command \\hidecallgraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command. Disabling a caller graph can be\n# accomplished by means of the command \\hidecallergraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot. For an explanation of the image formats see the section\n# output formats in the documentation of the dot tool (Graphviz (see:\n# http://www.graphviz.org/)).\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,\n# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,\n# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,\n# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and\n# png:gdiplus:gdiplus.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the\n# path where java can find the plantuml.jar file. If left blank, it is assumed\n# PlantUML is not used or called during a preprocessing step. Doxygen will\n# generate a warning when it encounters a \\startuml command in this case and\n# will not generate output for the diagram.\n\nPLANTUML_JAR_PATH      =\n\n# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a\n# configuration file for plantuml.\n\nPLANTUML_CFG_FILE      =\n\n# When using plantuml, the specified paths are searched for files specified by\n# the !include statement in a plantuml block.\n\nPLANTUML_INCLUDE_PATH  =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate\n# files that are used to generate the various graphs.\n#\n# Note: This setting is not only used for dot files but also for msc and\n# plantuml temporary files.\n# The default value is: YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "examples/CMakeLists.txt",
    "content": "find_package(Threads REQUIRED)\n\nset(COPYRIGHT \"Copyright [year], Your Name\")\nset(VENDOR \"Your Name\")\nset(DESCRIPTION \"Example app made with webview\")\nset(SHARED_SOURCES)\n\nif(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n    include(resources/macos/resources.cmake)\nelseif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n    include(resources/windows/resources.cmake)\nendif()\n\nadd_executable(webview_example_basic_c MACOSX_BUNDLE WIN32)\ntarget_sources(webview_example_basic_c PRIVATE basic.c ${SHARED_SOURCES})\ntarget_link_libraries(webview_example_basic_c PRIVATE webview::core_static)\n\nadd_executable(webview_example_basic_cc MACOSX_BUNDLE WIN32)\ntarget_sources(webview_example_basic_cc PRIVATE basic.cc ${SHARED_SOURCES})\ntarget_link_libraries(webview_example_basic_cc PRIVATE webview::core)\n\nadd_executable(webview_example_bind_c MACOSX_BUNDLE WIN32)\ntarget_sources(webview_example_bind_c PRIVATE bind.c ${SHARED_SOURCES})\ntarget_link_libraries(webview_example_bind_c PRIVATE webview::core_static Threads::Threads)\n\nif(MSVC)\n    # Disable some warnings when using MSVC\n    target_compile_definitions(webview_example_bind_c PRIVATE _CRT_SECURE_NO_WARNINGS)\nendif()\n\nadd_executable(webview_example_bind_cc MACOSX_BUNDLE WIN32)\ntarget_sources(webview_example_bind_cc PRIVATE bind.cc ${SHARED_SOURCES})\ntarget_link_libraries(webview_example_bind_cc PRIVATE webview::core Threads::Threads)\n"
  },
  {
    "path": "examples/basic.c",
    "content": "#include \"webview/webview.h\"\n#include <stddef.h>\n\n#ifdef _WIN32\n#include <windows.h>\n#endif\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,\n                   int nCmdShow) {\n  (void)hInst;\n  (void)hPrevInst;\n  (void)lpCmdLine;\n  (void)nCmdShow;\n#else\nint main(void) {\n#endif\n  webview_t w = webview_create(0, NULL);\n  webview_set_title(w, \"Basic Example\");\n  webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);\n  webview_set_html(w, \"Thanks for using webview!\");\n  webview_run(w);\n  webview_destroy(w);\n  return 0;\n}\n"
  },
  {
    "path": "examples/basic.cc",
    "content": "#include \"webview/webview.h\"\n\n#include <iostream>\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,\n                   LPSTR /*lpCmdLine*/, int /*nCmdShow*/) {\n#else\nint main() {\n#endif\n  try {\n    webview::webview w(false, nullptr);\n    w.set_title(\"Basic Example\");\n    w.set_size(480, 320, WEBVIEW_HINT_NONE);\n    w.set_html(\"Thanks for using webview!\");\n    w.run();\n  } catch (const webview::exception &e) {\n    std::cerr << e.what() << '\\n';\n    return 1;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "examples/bind.c",
    "content": "#include \"webview/webview.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <pthread.h>\n#include <unistd.h>\n#endif\n\n// Only used to suppress warnings caused by unused parameters.\n#define UNUSED(x) (void)x\n\ntypedef struct {\n  void *arg;\n  void (*next_fn)(void *);\n  void (*free_fn)(void *);\n} start_routine_wrapper_arg_t;\n\n#ifdef _WIN32\nDWORD __stdcall start_routine_wrapper(void *wrapper_arg) {\n  start_routine_wrapper_arg_t *arg = (start_routine_wrapper_arg_t *)wrapper_arg;\n  arg->next_fn(arg->arg);\n  arg->free_fn(wrapper_arg);\n  return 0;\n}\n#else\nvoid *start_routine_wrapper(void *wrapper_arg) {\n  start_routine_wrapper_arg_t *arg = (start_routine_wrapper_arg_t *)wrapper_arg;\n  arg->next_fn(arg->arg);\n  arg->free_fn(wrapper_arg);\n  return NULL;\n}\n#endif\n\n// Creates a thread with the given start routine and argument passed to\n// the start routine. Returns 0 on success and -1 on failure.\nint thread_create(void (*start_routine)(void *), void *arg) {\n  start_routine_wrapper_arg_t *wrapper_arg =\n      (start_routine_wrapper_arg_t *)malloc(\n          sizeof(start_routine_wrapper_arg_t));\n  wrapper_arg->arg = arg;\n  wrapper_arg->next_fn = start_routine;\n  wrapper_arg->free_fn = free;\n\n#ifdef _WIN32\n  HANDLE thread =\n      CreateThread(NULL, 0, start_routine_wrapper, wrapper_arg, 0, NULL);\n  if (thread) {\n    CloseHandle(thread);\n    return 0;\n  }\n  return -1;\n#else\n  pthread_t thread;\n  int error = pthread_create(&thread, NULL, start_routine_wrapper, wrapper_arg);\n  if (error == 0) {\n    pthread_detach(thread);\n    return 0;\n  }\n  return -1;\n#endif\n}\n\n// Make the current thread sleep for the given number of seconds.\nvoid thread_sleep(int seconds) {\n#ifdef _WIN32\n  Sleep(seconds * 1000);\n#else\n  sleep(seconds);\n#endif\n}\n\ntypedef struct {\n  webview_t w;\n  long count;\n} context_t;\n\nstatic const char html[] = \"\\\n<div>\\n\\\n  <button id=\\\"increment\\\">+</button>\\n\\\n  <button id=\\\"decrement\\\">−</button>\\n\\\n  <span>Counter: <span id=\\\"counterResult\\\">0</span></span>\\n\\\n</div>\\n\\\n<hr />\\n\\\n<div>\\n\\\n  <button id=\\\"compute\\\">Compute</button>\\n\\\n  <span>Result: <span id=\\\"computeResult\\\">(not started)</span></span>\\n\\\n</div>\\n\\\n<script type=\\\"module\\\">\\n\\\n  const getElements = ids => Object.assign({}, ...ids.map(\\n\\\n    id => ({ [id]: document.getElementById(id) })));\\n\\\n  const ui = getElements([\\n\\\n    \\\"increment\\\", \\\"decrement\\\", \\\"counterResult\\\", \\\"compute\\\",\\n\\\n    \\\"computeResult\\\"\\n\\\n  ]);\\n\\\n  ui.increment.addEventListener(\\\"click\\\", async () => {\\n\\\n    ui.counterResult.textContent = await window.count(1);\\n\\\n  });\\n\\\n  ui.decrement.addEventListener(\\\"click\\\", async () => {\\n\\\n    ui.counterResult.textContent = await window.count(-1);\\n\\\n  });\\n\\\n  ui.compute.addEventListener(\\\"click\\\", async () => {\\n\\\n    ui.compute.disabled = true;\\n\\\n    ui.computeResult.textContent = \\\"(pending)\\\";\\n\\\n    ui.computeResult.textContent = await window.compute(6, 7);\\n\\\n    ui.compute.disabled = false;\\n\\\n  });\\n\\\n</script>\";\n\nvoid count(const char *id, const char *req, void *arg) {\n  context_t *context = (context_t *)arg;\n  // Imagine that params->req is properly parsed or use your own JSON parser.\n  long direction = strtol(req + 1, NULL, 10);\n  char result[10] = {0};\n  (void)sprintf(result, \"%ld\", context->count += direction);\n  webview_return(context->w, id, 0, result);\n}\n\ntypedef struct {\n  webview_t w;\n  char *id;\n  char *req;\n} compute_thread_params_t;\n\ncompute_thread_params_t *\ncompute_thread_params_create(webview_t w, const char *id, const char *req) {\n  compute_thread_params_t *params =\n      (compute_thread_params_t *)malloc(sizeof(compute_thread_params_t));\n  params->w = w;\n  params->id = (char *)malloc(strlen(id) + 1);\n  params->req = (char *)malloc(strlen(req) + 1);\n  strcpy(params->id, id);\n  strcpy(params->req, req);\n  return params;\n}\n\nvoid compute_thread_params_free(compute_thread_params_t *p) {\n  free(p->req);\n  free(p->id);\n  free(p);\n}\n\nvoid compute_thread_proc(void *arg) {\n  compute_thread_params_t *params = (compute_thread_params_t *)arg;\n  // Simulate load.\n  thread_sleep(1);\n  // Imagine that params->req is properly parsed or use your own JSON parser.\n  const char *result = \"42\";\n  webview_return(params->w, params->id, 0, result);\n  compute_thread_params_free(params);\n}\n\nvoid compute(const char *id, const char *req, void *arg) {\n  context_t *context = (context_t *)arg;\n  compute_thread_params_t *params =\n      compute_thread_params_create(context->w, id, req);\n  // Create a thread and forget about it for the sake of simplicity.\n  if (thread_create(compute_thread_proc, params) != 0) {\n    compute_thread_params_free(params);\n  }\n}\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,\n                   int nCmdShow) {\n  (void)hInst;\n  (void)hPrevInst;\n  (void)lpCmdLine;\n  (void)nCmdShow;\n#else\nint main(void) {\n#endif\n  webview_t w = webview_create(0, NULL);\n  context_t context = {.w = w, .count = 0};\n  webview_set_title(w, \"Bind Example\");\n  webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);\n\n  // A binding that counts up or down and immediately returns the new value.\n  webview_bind(w, \"count\", count, &context);\n\n  // A binding that creates a new thread and returns the result at a later time.\n  webview_bind(w, \"compute\", compute, &context);\n\n  webview_set_html(w, html);\n  webview_run(w);\n  webview_destroy(w);\n  return 0;\n}\n"
  },
  {
    "path": "examples/bind.cc",
    "content": "#include \"webview/webview.h\"\n\n#include <chrono>\n#include <iostream>\n#include <string>\n#include <thread>\n\nconstexpr const auto html =\n    R\"html(\n<div>\n  <button id=\"increment\">+</button>\n  <button id=\"decrement\">−</button>\n  <span>Counter: <span id=\"counterResult\">0</span></span>\n</div>\n<hr />\n<div>\n  <button id=\"compute\">Compute</button>\n  <span>Result: <span id=\"computeResult\">(not started)</span></span>\n</div>\n<script type=\"module\">\n  const getElements = ids => Object.assign({}, ...ids.map(\n    id => ({ [id]: document.getElementById(id) })));\n  const ui = getElements([\n    \"increment\", \"decrement\", \"counterResult\", \"compute\",\n    \"computeResult\"\n  ]);\n  ui.increment.addEventListener(\"click\", async () => {\n    ui.counterResult.textContent = await window.count(1);\n  });\n  ui.decrement.addEventListener(\"click\", async () => {\n    ui.counterResult.textContent = await window.count(-1);\n  });\n  ui.compute.addEventListener(\"click\", async () => {\n    ui.compute.disabled = true;\n    ui.computeResult.textContent = \"(pending)\";\n    ui.computeResult.textContent = await window.compute(6, 7);\n    ui.compute.disabled = false;\n  });\n</script>)html\";\n\n#ifdef _WIN32\nint WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,\n                   LPSTR /*lpCmdLine*/, int /*nCmdShow*/) {\n#else\nint main() {\n#endif\n  try {\n    long count = 0;\n\n    webview::webview w(true, nullptr);\n    w.set_title(\"Bind Example\");\n    w.set_size(480, 320, WEBVIEW_HINT_NONE);\n\n    // A binding that counts up or down and immediately returns the new value.\n    w.bind(\"count\", [&](const std::string &req) -> std::string {\n      // Imagine that req is properly parsed or use your own JSON parser.\n      auto direction = std::stol(req.substr(1, req.size() - 1));\n      return std::to_string(count += direction);\n    });\n\n    // A binding that creates a new thread and returns the result at a later time.\n    w.bind(\n        \"compute\",\n        [&](const std::string &id, const std::string &req, void * /*arg*/) {\n          // Create a thread and forget about it for the sake of simplicity.\n          std::thread([&, id, req] {\n            // Simulate load.\n            std::this_thread::sleep_for(std::chrono::seconds(1));\n            // Imagine that req is properly parsed or use your own JSON parser.\n            const auto *result = \"42\";\n            w.resolve(id, 0, result);\n          }).detach();\n        },\n        nullptr);\n\n    w.set_html(html);\n    w.run();\n  } catch (const webview::exception &e) {\n    std::cerr << e.what() << '\\n';\n    return 1;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "examples/resources/macos/resources.cmake",
    "content": "set(MACOSX_BUNDLE_BUNDLE_NAME \"${PROJECT_NAME}\")\nset(MACOSX_BUNDLE_BUNDLE_VERSION \"${PROJECT_VERSION}\")\nset(MACOSX_BUNDLE_COPYRIGHT \"${COPYRIGHT}\")\nset(MACOSX_BUNDLE_GUI_IDENTIFIER \"com.${PROJECT_NAME}.example\")\nset(MACOSX_BUNDLE_ICON_FILE \"app_icon.icns\")\nset(MACOSX_BUNDLE_SHORT_VERSION_STRING \"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}\")\nset(APP_ICON_FILE \"${CMAKE_CURRENT_LIST_DIR}/${MACOSX_BUNDLE_ICON_FILE}\")\n\nset_source_files_properties(${APP_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION \"Resources\")\nlist(APPEND SHARED_SOURCES \"${APP_ICON_FILE}\")\n"
  },
  {
    "path": "examples/resources/windows/resources.cmake",
    "content": "configure_file(\"${CMAKE_CURRENT_LIST_DIR}/version.rc.in\" \"resources/windows/version.rc\" @ONLY)\nlist(APPEND SHARED_SOURCES\n    \"resources/windows/resources.rc\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/resources/windows/version.rc\")\n"
  },
  {
    "path": "examples/resources/windows/resources.rc",
    "content": "#define IDI_APPLICATION 32512\n\n// An application icon can be specified with a low ID\n//100 ICON \"webview.ico\"\n\n// Window icon (may also be used as the application icon)\nIDI_APPLICATION ICON \"webview.ico\"\n"
  },
  {
    "path": "examples/resources/windows/version.rc.in",
    "content": "#include <winver.h>\n#pragma code_page(65001)\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0\nPRODUCTVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0\nFILEFLAGSMASK 0x3fL\n#ifdef _DEBUG\nFILEFLAGS 0x1L\n#else\nFILEFLAGS 0x0L\n#endif\nFILEOS 0x40004L\nFILETYPE 0x2L\nFILESUBTYPE 0x0L\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"040904b0\"\n        BEGIN\n            VALUE \"CompanyName\", \"@VENDOR@\"\n            VALUE \"FileDescription\", \"@DESCRIPTION@\"\n            VALUE \"FileVersion\", \"@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.0\"\n            VALUE \"LegalCopyright\", \"@COPYRIGHT@\"\n            VALUE \"ProductName\", \"@PROJECT_NAME@\"\n            VALUE \"ProductVersion\", \"@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.0\"\n        END\n    END\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x409, 1200\n    END\nEND\n"
  },
  {
    "path": "gcovr.cfg",
    "content": "html-details = yes\noutput = build/coverage/\nfilter = ^core/include/\ngcov-exclude-directories = build/_deps/\ndelete-gcov-files = yes\nexclude = build/_deps/\nmerge-mode-functions = separate\n"
  },
  {
    "path": "gcovr.ci.cfg",
    "content": "filter = ^core/include/\ngcov-exclude-directories = build/_deps/\nexclude = build/_deps/\nmerge-mode-functions = separate\n"
  },
  {
    "path": "packaging/CMakeLists.txt",
    "content": "set(CPACK_PACKAGE_NAME webview)\nset(CPACK_PACKAGE_VENDOR webview organization)\nset(CPACK_PACKAGE_VERSION ${WEBVIEW_VERSION})\nset(CPACK_PACKAGE_DESCRIPTION_SUMMARY \"A tiny cross-platform webview library for C/C++ to build modern cross-platform GUIs\")\nset(CPACK_PACKAGE_INSTALL_DIRECTORY \"${CPACK_PACKAGE_NAME}\")\nset(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE)\nset(CPACK_VERBATIM_VARIABLES TRUE)\n\nstring(TOLOWER \"${CMAKE_GENERATOR_PLATFORM}\" CMAKE_GENERATOR_PLATFORM_LC)\nif(MSVC)\n    if(CMAKE_GENERATOR_PLATFORM_LC STREQUAL \"arm64\")\n        set(CMAKE_SYSTEM_PROCESSOR arm64)\n    elseif(CMAKE_GENERATOR_PLATFORM_LC STREQUAL \"amd64\" OR CMAKE_GENERATOR_PLATFORM_LC STREQUAL \"x64\")\n        set(CMAKE_SYSTEM_PROCESSOR x86_64)\n    elseif(CMAKE_GENERATOR_PLATFORM_LC STREQUAL \"win32\" OR CMAKE_GENERATOR_PLATFORM_LC STREQUAL \"x86\")\n        set(CMAKE_SYSTEM_PROCESSOR x86)\n    endif()\nendif()\n\nstring(TOLOWER \"${CMAKE_SYSTEM_NAME}\" CMAKE_SYSTEM_NAME_LC)\nstring(TOLOWER \"${CMAKE_SYSTEM_PROCESSOR}\" CMAKE_SYSTEM_PROCESSOR_LC)\nstring(TOLOWER \"${CMAKE_CXX_COMPILER_ID}\" CMAKE_CXX_COMPILER_ID_LC)\n\nif(MSVC AND MSVC_TOOLSET_VERSION)\n    set(COMPILER_VERSION \"${MSVC_TOOLSET_VERSION}\")\nelse()\n    string(REPLACE \".\" \";\" COMPILER_VERSION_LIST \"${CMAKE_CXX_COMPILER_VERSION}\")\n    list(GET COMPILER_VERSION_LIST 0 COMPILER_VERSION_MAJOR)\n    list(GET COMPILER_VERSION_LIST 1 COMPILER_VERSION_MINOR)\n    set(COMPILER_VERSION \"${COMPILER_VERSION_MAJOR}.${COMPILER_VERSION_MINOR}\")\nendif()\nset(COMPILER \"${CMAKE_CXX_COMPILER_ID_LC}_${COMPILER_VERSION}\")\n\nif(WEBVIEW_USE_STATIC_MSVC_RUNTIME)\n    set(RUNTIME_SUFFIX \"-static_rt\")\nendif()\n\nif(APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES \";\")\n    set(PACKAGE_NAME_ARCH universal)\nelse()\n    set(PACKAGE_NAME_ARCH ${CMAKE_SYSTEM_PROCESSOR_LC})\nendif()\n\nif((MSYS OR MINGW) AND DEFINED ENV{MSYSTEM})\n    string(TOLOWER \"$ENV{MSYSTEM}\" MSYSTEM)\n    set(MSYSTEM_SUFFIX \"-${MSYSTEM}\")\nendif()\n\nfile(TO_CMAKE_PATH \"${PROJECT_BINARY_DIR}\" IGNORED_BUILD_DIR)\nstring(REPLACE \"\\\\\" \"\\\\\\\\\" IGNORED_BUILD_DIR \"${IGNORED_BUILD_DIR}\")\nset(CPACK_SOURCE_IGNORE_FILES\n    \\\\.git/\n    \"^${IGNORED_BUILD_DIR}\"\n)\nset(CPACK_SOURCE_GENERATOR TGZ)\n\n# File names\nset(WEBVIEW_ARCHIVE_SYSTEM_ARCH_FILE_NAME \"${CPACK_PACKAGE_NAME}_v${CPACK_PACKAGE_VERSION}-${COMPILER}${MSYSTEM_SUFFIX}${RUNTIME_SUFFIX}-${CMAKE_SYSTEM_NAME_LC}-${PACKAGE_NAME_ARCH}\")\nset(WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME \"${CPACK_PACKAGE_NAME}_v${CPACK_PACKAGE_VERSION}\")\nset(CPACK_SOURCE_PACKAGE_FILE_NAME \"${WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME}-source\")\n\n# Set up custom packaging script for the \"External\" CPack generator\nconfigure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/external_package.cmake.in\" \"${CMAKE_CURRENT_BINARY_DIR}/external_package.cmake\" @ONLY)\nset(CPACK_EXTERNAL_PACKAGE_SCRIPT \"${CMAKE_CURRENT_BINARY_DIR}/external_package.cmake\")\nset(CPACK_EXTERNAL_ENABLE_STAGING TRUE)\n\ninclude(CPack)\n"
  },
  {
    "path": "packaging/external_package.cmake.in",
    "content": "set(WEBVIEW_ARCHIVE_SYSTEM_ARCH_FILE_NAME \"@WEBVIEW_ARCHIVE_SYSTEM_ARCH_FILE_NAME@\")\nset(WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME \"@WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME@\")\nset(WEBVIEW_PACKAGE_AMALGAMATION \"@WEBVIEW_PACKAGE_AMALGAMATION@\")\nset(WEBVIEW_PACKAGE_DOCS \"@WEBVIEW_PACKAGE_DOCS@\")\nset(WEBVIEW_PACKAGE_HEADERS \"@WEBVIEW_PACKAGE_HEADERS@\")\nset(WEBVIEW_PACKAGE_LIB \"@WEBVIEW_PACKAGE_LIB@\")\nset(CMAKE_INSTALL_DOCDIR \"@CMAKE_INSTALL_DOCDIR@\")\n\nfunction(create_archive_for_components)\n    # Parse function arguments\n    set(COMPONENT_INDEX 0)\n    set(ARG_INDEX 0)\n    while(ARG_INDEX LESS \"${ARGC}\")\n        set(ARG \"${ARGV${ARG_INDEX}}\")\n        if(ARG STREQUAL \"ARCHIVE\")\n            math(EXPR ARG_INDEX \"${ARG_INDEX}+1\")\n            set(ARCHIVE \"${ARGV${ARG_INDEX}}\")\n        elseif(ARG STREQUAL \"COMPONENT\")\n            math(EXPR SUB_ARGC \"${ARG_INDEX}+4\")\n            while(ARG_INDEX LESS \"${SUB_ARGC}\")\n                set(SUB_ARG \"${ARGV${ARG_INDEX}}\")\n                if(SUB_ARG STREQUAL \"NAME\")\n                    math(EXPR ARG_INDEX \"${ARG_INDEX}+1\")\n                    set(\"COMPONENT${COMPONENT_INDEX}_NAME\" \"${ARGV${ARG_INDEX}}\")\n                elseif(SUB_ARG STREQUAL \"SUBDIR\")\n                    math(EXPR ARG_INDEX \"${ARG_INDEX}+1\")\n                    set(\"COMPONENT${COMPONENT_INDEX}_SUBDIR\" \"${ARGV${ARG_INDEX}}\")\n                endif()\n                math(EXPR ARG_INDEX \"${ARG_INDEX}+1\")\n            endwhile()\n            math(EXPR COMPONENT_INDEX \"${COMPONENT_INDEX}+1\")\n            continue()\n        else()\n            message(FATAL_ERROR \"Unparsed arg ${ARG_INDEX}: ${ARGV${ARG_INDEX}}\")\n        endif()\n        math(EXPR ARG_INDEX \"${ARG_INDEX}+1\")\n    endwhile()\n    math(EXPR COMPONENT_COUNT \"${COMPONENT_INDEX}\")\n\n    # Build list of component names\n    set(COMPONENT_NAMES)\n    set(COMPONENT_INDEX 0)\n    while(COMPONENT_INDEX LESS \"${COMPONENT_COUNT}\")\n        list(APPEND COMPONENT_NAMES \"${COMPONENT${COMPONENT_INDEX}_NAME}\")\n        math(EXPR COMPONENT_INDEX \"${COMPONENT_INDEX}+1\")\n    endwhile()\n\n    string(SHA256 NAME_HASH \"${COMPONENT_NAMES}\")\n    set(TEMP_DIR \"${CPACK_TEMPORARY_DIRECTORY}/${NAME_HASH}\")\n\n    # Consolidate files from each component's staging directory\n    set(COMPONENT_INDEX 0)\n    while(COMPONENT_INDEX LESS \"${COMPONENT_COUNT}\")\n        set(COMPONENT_NAME \"${COMPONENT${COMPONENT_INDEX}_NAME}\")\n        set(COMPONENT_SUBDIR \"${COMPONENT${COMPONENT_INDEX}_SUBDIR}\")\n        if(\"${COMPONENT_SUBDIR}\" STREQUAL \"\")\n            set(COMPONENT_SUBDIR \".\")\n        endif()\n        file(GLOB_RECURSE COMPONENT_FILES\n            RELATIVE \"${CPACK_TEMPORARY_DIRECTORY}/${COMPONENT_NAME}/${COMPONENT_SUBDIR}\"\n            \"${CPACK_TEMPORARY_DIRECTORY}/${COMPONENT_NAME}/${COMPONENT_SUBDIR}/**\")\n        foreach(COMPONENT_FILE IN LISTS COMPONENT_FILES)\n            get_filename_component(COMPONENT_DIR \"${TEMP_DIR}/${COMPONENT_FILE}\" DIRECTORY)\n            file(COPY \"${CPACK_TEMPORARY_DIRECTORY}/${COMPONENT_NAME}/${COMPONENT_SUBDIR}/${COMPONENT_FILE}\" DESTINATION \"${COMPONENT_DIR}\")\n        endforeach()\n        math(EXPR COMPONENT_INDEX \"${COMPONENT_INDEX}+1\")\n    endwhile()\n\n    # Create archive\n    file(GLOB_RECURSE TEMP_FILES RELATIVE \"${TEMP_DIR}\" \"${TEMP_DIR}/**\")\n    execute_process(COMMAND ${CMAKE_COMMAND} -E tar cz \"${ARCHIVE}\" ${TEMP_FILES}\n        WORKING_DIRECTORY \"${TEMP_DIR}\")\nendfunction()\n\nif(WEBVIEW_PACKAGE_DOCS)\n    # API documentation archive\n    create_archive_for_components(\n        ARCHIVE \"${CPACK_PACKAGE_DIRECTORY}/${WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME}-apidoc.tar.gz\"\n        COMPONENT NAME webview_api_docs SUBDIR \"${CMAKE_INSTALL_DOCDIR}\")\nendif()\n\nif(WEBVIEW_PACKAGE_HEADERS)\n    # Header archive\n    create_archive_for_components(\n        ARCHIVE \"${CPACK_PACKAGE_DIRECTORY}/${WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME}-headers.tar.gz\"\n        COMPONENT NAME webview_headers SUBDIR .)\nendif()\n\nif(WEBVIEW_PACKAGE_DOCS)\n    # Per-system/architecture development archive\n    set(DEV_PACKAGE_API_DOCS_ARGS COMPONENT NAME webview_api_docs SUBDIR .)\nendif()\n\nif(WEBVIEW_PACKAGE_LIB)\n    # CMake configuration and compiled libraries\n    create_archive_for_components(\n        ARCHIVE \"${CPACK_PACKAGE_DIRECTORY}/${WEBVIEW_ARCHIVE_SYSTEM_ARCH_FILE_NAME}-lib.tar.gz\"\n        ${DEV_PACKAGE_API_DOCS_ARGS}\n        COMPONENT NAME webview_cmake SUBDIR .\n        COMPONENT NAME webview_libraries SUBDIR .)\nendif()\n\nif(WEBVIEW_PACKAGE_AMALGAMATION)\n    # Amalgamated library\n    create_archive_for_components(\n        ARCHIVE \"${CPACK_PACKAGE_DIRECTORY}/${WEBVIEW_ARCHIVE_UNIVERSAL_FILE_NAME}-amalgamation.tar.gz\"\n        COMPONENT NAME webview_amalgamation SUBDIR .)\nendif()\n"
  },
  {
    "path": "packaging/test/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "packaging/test/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(example LANGUAGES C CXX)\n\n# Workaround for missing \"EventToken.h\" (used by MS WebView2) when targetting Windows\nif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n    include(CheckCXXSourceCompiles)\n    check_cxx_source_compiles(\"#include <eventtoken.h>\" HAVE_EVENTTOKEN_H)\n    if(NOT HAVE_EVENTTOKEN_H)\n        include_directories(../../compatibility/mingw/include)\n    endif()\nendif()\n\nfind_package(webview REQUIRED CONFIG)\n\nadd_executable(example WIN32 ../../examples/cc/basic/src/main.cc)\ntarget_link_libraries(example PRIVATE webview::core)\n"
  },
  {
    "path": "scripts/amalgamate/amalgamate.py",
    "content": "from argparse import ArgumentParser\nfrom dataclasses import dataclass, field\nimport graphlib\nimport os\nimport pathlib\nimport re\nimport shutil\nimport subprocess\nfrom tempfile import TemporaryDirectory\nfrom typing import List, MutableMapping, MutableSet, Sequence\n\n\n@dataclass\nclass Include:\n    path: os.PathLike\n    chunks: List[str] = field(default_factory=list)\n\n    def __eq__(self, other):\n        if isinstance(other, \"Include\"):\n            return self.path == other.path\n        return self.path == other\n\n    def __lt__(self, other):\n        if isinstance(other, \"Include\"):\n            return self.path < other.path\n        return self.path < other\n\n\n@dataclass\nclass ProcessorContext:\n    base_dir: os.PathLike\n    include_pattern = re.compile(\n        r'^\\s*#include \"([^\"]+)\"\\s*(?://\\s*(.+))?', re.M)\n    block_comment_pattern = re.compile(r\"^/\\*.*?\\*/\\n\", re.DOTALL)\n    visited_files: MutableSet[os.PathLike] = field(default_factory=set)\n    visited_copyright_notices: MutableSet[str] = field(default_factory=set)\n    ordered_copyright_notices: List[str] = field(default_factory=list)\n    graph: MutableMapping[str, MutableSet[str]] = field(default_factory=dict)\n    includes: MutableMapping[str, Include] = field(default_factory=dict)\n\n\ndef process_file(context: ProcessorContext, input: os.PathLike, search_dirs: Sequence[os.PathLike] = []):\n    input = os.path.realpath(\n        input if os.path.isabs(input) else os.path.join(\n            context.base_dir, input)\n    )\n\n    search_dirs = [os.path.realpath(\n        search_dir if os.path.isabs(search_dir) else os.path.join(\n            context.base_dir, search_dir)) for search_dir in search_dirs]\n\n    if input in context.visited_files:\n        return\n    context.visited_files.add(input)\n\n    if not os.path.exists(input):\n        raise Exception(\"Input file not found: {}\".format(input))\n\n    if os.path.isdir(input):\n        print(\"Processing directory: {}\".format(input))\n        for entry in os.scandir(input):\n            process_file(context, entry.path, search_dirs=search_dirs)\n        return\n\n    print(\"Processing file: {}\".format(input))\n\n    input_include_files = context.graph.setdefault(input, set())\n\n    with open(input, encoding=\"utf-8\") as f:\n        content = f.read()\n\n        content = context.block_comment_pattern.sub(\n            lambda m: replace_copyright(context, m), content\n        ).strip()\n\n        input_parent_dir = os.path.dirname(input)\n        input_include = context.includes.setdefault(input, Include(input))\n\n        end = 0\n        for m in context.include_pattern.finditer(content):\n            input_include.chunks.append(content[end: m.start(0)])\n            end = m.end(0)\n\n            comment_instruction = m[2]\n            if comment_instruction is not None:\n                skip_include = comment_instruction == \"amalgamate(skip)\"\n\n            include_file_in_parent_dir = os.path.realpath(\n                os.path.join(input_parent_dir, m[1]))\n            if include_file_in_parent_dir in context.visited_files:\n                input_include_files.add(include_file_in_parent_dir)\n                continue\n            if os.path.exists(include_file_in_parent_dir):\n                input_include_files.add(include_file_in_parent_dir)\n                process_file(context, include_file_in_parent_dir,\n                             search_dirs=search_dirs)\n                continue\n\n            include_file_in_search_dir_found = False\n            for search_dir in search_dirs:\n                include_file_in_search_dir = os.path.realpath(\n                    os.path.join(search_dir, m[1]))\n                if include_file_in_search_dir in context.visited_files:\n                    input_include_files.add(include_file_in_search_dir)\n                    include_file_in_search_dir_found = True\n                    break\n                if os.path.exists(include_file_in_search_dir):\n                    input_include_files.add(include_file_in_search_dir)\n                    process_file(context, include_file_in_search_dir,\n                                 search_dirs=search_dirs)\n                    include_file_in_search_dir_found = True\n                    break\n            if include_file_in_search_dir_found:\n                continue\n\n            if skip_include:\n                print(\"Skipped: {}\".format(m[1]))\n                input_include.chunks.append(m[0])\n                continue\n\n            raise Exception(\"Not found: {}\".format(m[1]))\n        input_include.chunks.append(content[end:])\n\n\ndef replace_copyright(context: ProcessorContext, match: re.Match[str]):\n    if \"copyright\".casefold() not in match[0].casefold():\n        return match[0]\n    hashed = hash(match[0])\n    if hashed in context.visited_copyright_notices:\n        return \"\"\n    context.visited_copyright_notices.add(hashed)\n    context.ordered_copyright_notices.append(match[0].strip())\n    return \"\"\n\n\ndef amalgamate(\n    base_dir: os.PathLike, inputs: Sequence[os.PathLike], output: os.PathLike,\n    search_dirs: Sequence[os.PathLike] = []\n):\n    context = ProcessorContext(base_dir=base_dir)\n    for input in inputs:\n        process_file(context, input, search_dirs=search_dirs)\n    output = os.path.realpath(output)\n    print(\"Sorting...\")\n    graph = dict(\n        sorted(\n            tuple((k, sorted(v)) for k, v in context.graph.items()), key=lambda i: i[0]\n        )\n    )\n    sorter = graphlib.TopologicalSorter(graph)\n    ordered_includes = tuple(\n        map(lambda x: context.includes[x], sorter.static_order()))\n    os.makedirs(os.path.dirname(output), exist_ok=True)\n    with open(output, mode=\"w\", encoding=\"utf-8\") as f:\n        if len(context.ordered_copyright_notices) > 0:\n            print(\"Embedding copyright notices...\")\n            for notice in context.ordered_copyright_notices:\n                f.write(notice)\n                f.write(\"\\n\")\n        for include in ordered_includes:\n            if len(include.chunks) > 0:\n                posix_include_relative_path = pathlib.Path(\n                    os.path.relpath(include.path, context.base_dir)\n                ).as_posix()\n                print(\"Embedding file: {}\".format(include.path))\n                f.write(\"// file begin: {}\\n\".format(posix_include_relative_path))\n                for chunk in include.chunks:\n                    f.write(chunk)\n                f.write(\"\\n// file end: {}\\n\".format(posix_include_relative_path))\n\n\ndef reformat_file(file: os.PathLike, clang_format_exe: os.PathLike):\n    file = os.path.realpath(file)\n    resolved_clang_format_exe = shutil.which(clang_format_exe)\n    if resolved_clang_format_exe is None:\n        raise Exception(\"clang-format not found: {}\".format(clang_format_exe))\n    print(\"Reformatting file: {}\".format(file))\n    subprocess.check_call((resolved_clang_format_exe, \"-i\", file))\n\n\ndef main(options):\n    base_dir = os.getcwd() if options.base is None else options.base\n    output_path = os.path.realpath(options.output)\n    # Use a suffix that clang-format recognizes as C++\n    with TemporaryDirectory() as temp_dir:\n        try:\n            amalgamated_path = os.path.join(temp_dir, \"amalgamated.hh\")\n            amalgamate(base_dir, options.input, amalgamated_path,\n                       search_dirs=options.search)\n            reformat_file(amalgamated_path,\n                          clang_format_exe=options.clang_format_exe)\n            os.makedirs(os.path.dirname(output_path), exist_ok=True)\n            shutil.move(amalgamated_path, output_path)\n            print(\"Saved output to file: {}\".format(output_path))\n        finally:\n            shutil.rmtree(temp_dir)\n\n\ndef parse_args():\n    parser = ArgumentParser(\n        prog=\"amalgamate\",\n        description=\"Combines a C or C++ source/header hierarchy into one file\",\n    )\n    parser.add_argument(\"--base\", help=\"Base directory\")\n    parser.add_argument(\n        \"--clang-format-exe\", help=\"clang-format executable\", default=\"clang-format\"\n    )\n    parser.add_argument(\"--search\", nargs=\"+\", help=\"Header search directory\")\n    parser.add_argument(\"--output\", help=\"Output file\")\n    parser.add_argument(\"input\", nargs=\"+\", help=\"Input file\")\n    return parser.parse_args()\n\n\nif __name__ == \"__main__\":\n    main(parse_args())\n"
  },
  {
    "path": "scripts/amalgamate/test/.gitignore",
    "content": "build/\n"
  },
  {
    "path": "scripts/amalgamate/test/main.c",
    "content": "#include \"webview_amalgamation.h\"\n#include <stddef.h>\n\nint main(void) {\n  webview_t w = webview_create(0, NULL);\n  webview_destroy(w);\n  return 0;\n}\n"
  },
  {
    "path": "scripts/amalgamate/test/main.cc",
    "content": "#include \"webview_amalgamation.h\"\n\nint main() {\n  webview::webview w(false, nullptr);\n  return 0;\n}\n"
  },
  {
    "path": "scripts/amalgamate/test/webview.cc",
    "content": "#include \"webview_amalgamation.h\"\n"
  },
  {
    "path": "test_driver/CMakeLists.txt",
    "content": "add_library(webview_test_driver STATIC)\ntarget_sources(webview_test_driver PRIVATE src/test_driver.cc)\ntarget_include_directories(webview_test_driver PUBLIC include)\n"
  },
  {
    "path": "test_driver/cmake/discovery.cmake",
    "content": "set(WEBVIEW_TEST_DISCOVERY_DIR ${CMAKE_CURRENT_LIST_DIR})\n\nfunction(webview_discover_tests TARGET)\n    cmake_parse_arguments(\n        \"TEST\"\n        \"\"\n        \"WORKING_DIRECTORY;TIMEOUT\"\n        \"TIMEOUT_AFTER_MATCH\"\n        ${ARGN}\n    )\n\n    SET(TEST_DRIVER_CONFIG_FILE_BASE \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_test_driver\")\n    if(IS_MULTI_CONFIG)\n        set(TEST_DRIVER_CONFIG_FILE \"${TEST_DRIVER_CONFIG_FILE_BASE}-$<CONFIG>.cmake\")\n    else()\n        set(TEST_DRIVER_CONFIG_FILE \"${TEST_DRIVER_CONFIG_FILE_BASE}.cmake\")\n    endif()\n\n    set(TEST_INCLUDE_FILE \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_test_include.cmake\")\n    set(TEST_DRIVER_INCLUDE_FILE \"${WEBVIEW_TEST_DISCOVERY_DIR}/discovery.cmake\")\n\n    add_custom_command(\n        TARGET \"${TARGET}\" POST_BUILD\n        BYPRODUCTS \"${TEST_INCLUDE_FILE}\" \"${TEST_DRIVER_CONFIG_FILE}\"\n        COMMAND \"${CMAKE_COMMAND}\"\n            -D \"IS_MULTI_CONFIG=${IS_MULTI_CONFIG}\"\n            -D \"BUILD_CONFIG=$<CONFIG>\"\n            -D \"TARGET=${TARGET}\"\n            -D \"TEST_DRIVER_CONFIG_FILE_BASE=${TEST_DRIVER_CONFIG_FILE_BASE}\"\n            -D \"TEST_DRIVER=$<TARGET_FILE:${TARGET}>\"\n            -D \"TEST_INCLUDE_FILE=${TEST_INCLUDE_FILE}\"\n            -D \"TEST_DRIVER_CONFIG_FILE=${TEST_DRIVER_CONFIG_FILE}\"\n            -D \"TEST_DRIVER_INCLUDE_FILE=${TEST_DRIVER_INCLUDE_FILE}\"\n            -D \"TEST_TIMEOUT=${TEST_TIMEOUT}\"\n            -D \"TEST_TIMEOUT_AFTER_MATCH=${TEST_TIMEOUT_AFTER_MATCH}\"\n            -P \"${WEBVIEW_TEST_DISCOVERY_DIR}/generate_includes.cmake\"\n        WORKING_DIRECTORY \"${TEST_WORKING_DIRECTORY}\"\n        VERBATIM\n    )\n\n    set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES \"${TEST_INCLUDE_FILE}\")\nendfunction()\n\nfunction(webview_discover_tests_impl TEST_DRIVER)\n    execute_process(\n        COMMAND \"${TEST_DRIVER}\" --list\n        OUTPUT_VARIABLE TEST_DRIVER_OUTPUT\n        RESULT_VARIABLE TEST_DRIVER_RESULT\n    )\n    string(STRIP \"${TEST_DRIVER_OUTPUT}\" TEST_DRIVER_OUTPUT)\n    string(REGEX REPLACE \"(;)\" \"\\\\\\\\\\\\1\" TEST_LIST \"${TEST_DRIVER_OUTPUT}\")\n    string(REGEX REPLACE \"[\\r\\n]+\" \";\" TEST_LIST \"${TEST_LIST}\")\n    foreach(TEST_LIST_ITEM IN LISTS TEST_LIST)\n        add_test(\n            \"${TEST_LIST_ITEM}\"\n            \"${TEST_DRIVER}\" \"${TEST_LIST_ITEM}\"\n        )\n        if(DEFINED TEST_TIMEOUT AND NOT TEST_TIMEOUT STREQUAL \"\")\n            set_tests_properties(TEST \"${TEST_LIST_ITEM}\" PROPERTIES TIMEOUT \"${TEST_TIMEOUT}\")\n        endif()\n        if(DEFINED TEST_TIMEOUT_AFTER_MATCH AND NOT TEST_TIMEOUT_AFTER_MATCH STREQUAL \"\")\n            list(GET TEST_TIMEOUT_AFTER_MATCH 0 TIMEOUT)\n            list(GET TEST_TIMEOUT_AFTER_MATCH 1 PATTERN)\n            # Originally TIMEOUT_AFTER_MATCH is a regex pattern but here we escape regex special characters\n            string(REGEX REPLACE [=[([\\\\|{([+*?.)}])]=] \"\\\\\\\\\\\\1\" PATTERN \"${PATTERN}\")\n            set_tests_properties(TEST \"${TEST_LIST_ITEM}\" PROPERTIES TIMEOUT_AFTER_MATCH \"${TIMEOUT};${PATTERN}\")\n        endif()\n    endforeach()\nendfunction()\n"
  },
  {
    "path": "test_driver/cmake/generate_includes.cmake",
    "content": "file(WRITE \"${TEST_DRIVER_CONFIG_FILE}\"\n    \"set(TEST_DRIVER \\\"${TEST_DRIVER}\\\")\\n\"\n)\n\nfile(WRITE \"${TEST_INCLUDE_FILE}\"\n    \"set(TEST_DRIVER_INCLUDE_FILE \\\"${TEST_DRIVER_INCLUDE_FILE}\\\")\\n\"\n    \"set(TEST_DRIVER_CONFIG_FILE_BASE \\\"${TEST_DRIVER_CONFIG_FILE_BASE}\\\")\\n\"\n    \"set(TEST_TIMEOUT \\\"${TEST_TIMEOUT}\\\")\\n\"\n    \"set(TEST_TIMEOUT_AFTER_MATCH \\\"${TEST_TIMEOUT_AFTER_MATCH}\\\")\\n\"\n    \"include(\\\"\\${TEST_DRIVER_INCLUDE_FILE}\\\")\\n\"\n    \"set(TEST_DRIVER_SINGLE_CONFIG_FILE \\\"\\${TEST_DRIVER_CONFIG_FILE_BASE}.cmake\\\")\\n\"\n    \"set(TEST_DRIVER_MULTI_CONFIG_FILE \\\"\\${TEST_DRIVER_CONFIG_FILE_BASE}-\\${CTEST_CONFIGURATION_TYPE}.cmake\\\")\\n\"\n    \"if(EXISTS \\\"\\${TEST_DRIVER_MULTI_CONFIG_FILE}\\\")\\n\"\n    \"   include(\\\"\\${TEST_DRIVER_MULTI_CONFIG_FILE}\\\")\\n\"\n    \"else()\\n\"\n    \"   include(\\\"\\${TEST_DRIVER_SINGLE_CONFIG_FILE}\\\")\\n\"\n    \"endif()\\n\"\n    \"webview_discover_tests_impl(\\\"\\${TEST_DRIVER}\\\")\\n\"\n)\n"
  },
  {
    "path": "test_driver/include/webview/test_driver.hh",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2024 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#ifndef WEBVIEW_TEST_DRIVER_HH\n#define WEBVIEW_TEST_DRIVER_HH\n\n#include <exception>\n#include <functional>\n#include <map>\n#include <string>\n\nnamespace webview {\n\nstruct failure_info {\n  const char *condition;\n  const char *file;\n  int line;\n};\n\nstruct test_failure : public std::exception {\n  explicit test_failure(const failure_info &info) noexcept : m_info{info} {}\n  const char *what() const noexcept override { return \"test failure\"; }\n  const failure_info &info() const noexcept { return m_info; }\n\nprivate:\n  failure_info m_info;\n};\n\nclass test_reg {\npublic:\n  test_reg() = default;\n\n  test_reg(const char *name, std::function<void()> fn) noexcept\n      : m_name{name}, m_fn{std::move(fn)} {}\n\n  const std::string &name() const noexcept { return m_name; }\n  void invoke() const { m_fn(); }\n\nprivate:\n  std::string m_name;\n  std::function<void()> m_fn;\n};\n\nstruct auto_test_reg {\n  explicit auto_test_reg(test_reg reg) noexcept {\n    tests()[reg.name()] = std::move(reg);\n  }\n\n  static std::map<std::string, test_reg> &tests();\n};\n\n// NOLINTBEGIN(cppcoreguidelines-macro-usage, misc-use-anonymous-namespace)\n\n#define MAKE_TEST_CASE_NAME2(name, counter) name##counter\n#define MAKE_TEST_CASE_NAME(name, counter) MAKE_TEST_CASE_NAME2(name, counter)\n\n#define TEST_CASE_INTERNAL(name, counter)                                      \\\n  static void MAKE_TEST_CASE_NAME(webview_test_driver_case_, counter)();       \\\n  namespace {                                                                  \\\n  const ::webview::auto_test_reg                                               \\\n      MAKE_TEST_CASE_NAME(webview_test_driver_case_reg_, counter){             \\\n          {name, MAKE_TEST_CASE_NAME(webview_test_driver_case_, counter)}};    \\\n  }                                                                            \\\n  static void MAKE_TEST_CASE_NAME(webview_test_driver_case_, counter)()\n\n#define TEST_CASE(name) TEST_CASE_INTERNAL(name, __LINE__)\n\n#define REQUIRE(condition)                                                     \\\n  if (!static_cast<bool>(condition)) {                                         \\\n    throw ::webview::test_failure{                                             \\\n        ::webview::failure_info{#condition, __FILE__, __LINE__}};              \\\n  }\n\n#define REQUIRE_FALSE(condition)                                               \\\n  if (static_cast<bool>(condition)) {                                          \\\n    throw ::webview::test_failure{                                             \\\n        ::webview::failure_info{#condition, __FILE__, __LINE__}};              \\\n  }\n\n#define REQUIRE_THROW(exception, fn)                                           \\\n  {                                                                            \\\n    bool did_throw{};                                                          \\\n    try {                                                                      \\\n      fn();                                                                    \\\n    } catch (const exception &) {                                              \\\n      did_throw = true;                                                        \\\n    }                                                                          \\\n    REQUIRE(did_throw);                                                        \\\n  }\n\n#define SECTION(name)\n\n// NOLINTEND(cppcoreguidelines-macro-usage, misc-use-anonymous-namespace)\n\n} // namespace webview\n\n#endif // WEBVIEW_TEST_DRIVER_HH\n"
  },
  {
    "path": "test_driver/src/test_driver.cc",
    "content": "/*\n * MIT License\n *\n * Copyright (c) 2024 Steffen André Langnes\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#include \"webview/test_driver.hh\"\n\n#include <deque>\n#include <iomanip>\n#include <iostream>\n#include <string>\n\nnamespace webview {\n\nstd::map<std::string, test_reg> &auto_test_reg::tests() {\n  static std::map<std::string, test_reg> instance;\n  return instance;\n}\n\n} // namespace webview\n\nstruct failure_exit_codes {\n  enum type {\n    success = 0,\n    failure = 1,\n    exception_thrown = 2,\n    no_tests_found = 3,\n    test_not_found = 4\n  };\n};\n\nint cmd_help() {\n  std::cout << \"Usage: program [--[help|list]|test_name].\\n\";\n  return 0;\n}\n\nint cmd_list() {\n  using namespace webview;\n  auto &tests{auto_test_reg::tests()};\n  if (tests.empty()) {\n    std::cerr << \"No tests found.\\n\";\n    return failure_exit_codes::no_tests_found;\n  }\n  for (const auto &test : tests) {\n    std::cout << test.second.name() << '\\n';\n  }\n  return failure_exit_codes::success;\n}\n\nint cmd_run_test(const std::string &test_name) {\n  using namespace webview;\n  auto &tests{auto_test_reg::tests()};\n  auto found{tests.find(test_name)};\n  if (found == tests.end()) {\n    std::cerr << \"Test not found: \" << test_name << '\\n';\n    return failure_exit_codes::test_not_found;\n  }\n  auto exit_code{failure_exit_codes::failure};\n  const auto &test{found->second};\n  try {\n    test.invoke();\n    exit_code = failure_exit_codes::success;\n  } catch (const test_failure &e) {\n    const auto &info{e.info()};\n    std::cerr << \"Test \\\"\" << test.name() << \"\\\" failed [\" << info.condition\n              << \"] at \" << info.file << \":\" << info.line << \".\\n\";\n    exit_code = failure_exit_codes::failure;\n  } catch (const std::exception &e) {\n    std::cerr << \"Test \\\"\" << test.name()\n              << \"\\\" threw exception with message \\\"\" << e.what() << \"\\\".\\n\";\n    exit_code = failure_exit_codes::exception_thrown;\n  }\n  return exit_code;\n}\n\nint cmd_run_all_tests() {\n  using namespace webview;\n  auto &tests{auto_test_reg::tests()};\n  if (tests.empty()) {\n    return failure_exit_codes::no_tests_found;\n  }\n  size_t name_width{};\n  for (const auto &it : tests) {\n    const auto &test{it.second};\n    const auto name_size{test.name().size()};\n    if (name_size > name_width) {\n      name_width = name_size;\n    }\n  }\n  size_t success_count{};\n  for (const auto &it : tests) {\n    const auto &test{it.second};\n    std::cout << test.name() << std::setfill('.')\n              << std::setw(static_cast<int>(name_width - test.name().size()))\n              << \"\" << std::setw(0) << \": \";\n    try {\n      test.invoke();\n      ++success_count;\n      std::cout << \"OK\\n\";\n    } catch (const test_failure &e) {\n      const auto &info{e.info()};\n      std::cout << \"FAIL\\n\";\n      std::cerr << \"Test \\\"\" << test.name() << \"\\\" failed [\" << info.condition\n                << \"] at \" << info.file << \":\" << info.line << \".\\n\";\n    } catch (const std::exception &e) {\n      std::cout << \"FAIL\\n\";\n      std::cerr << \"Test \\\"\" << test.name()\n                << \"\\\" threw exception with message \\\"\" << e.what() << \"\\\".\\n\";\n    }\n  }\n  if (success_count == tests.size()) {\n    return failure_exit_codes::success;\n  }\n  return failure_exit_codes::failure;\n}\n\nint main(int argc, const char *argv[]) {\n  try {\n    const std::deque<std::string> args{argv, argv + argc};\n    if (args.size() > 1) {\n      const std::string &arg{args.at(1)};\n      if (arg == \"--help\") {\n        return cmd_help();\n      }\n      if (arg == \"--list\") {\n        return cmd_list();\n      }\n      return cmd_run_test(arg);\n    }\n    return cmd_run_all_tests();\n  } catch (const std::exception &e) {\n    std::cerr << \"Error: \" << e.what() << '\\n';\n    return failure_exit_codes::exception_thrown;\n  } catch (...) {\n    std::cerr << \"Unknown error.\\n\";\n    return failure_exit_codes::exception_thrown;\n  }\n}\n"
  },
  {
    "path": "webview.i",
    "content": "%module webview \n%{\n#include \"webview.h\"\n%}\n#define WEBVIEW_HINT_NONE 0\n#define WEBVIEW_HINT_MIN 1\n#define WEBVIEW_HINT_MAX 2\n#define WEBVIEW_HINT_FIXED 3\ntypedef void *webview_t;\nextern webview_t webview_create(int debug, void *window);\nextern void webview_destroy(webview_t w);\nextern void webview_run(webview_t w);\nextern void webview_terminate(webview_t w);\nextern void webview_dispatch(webview_t w, void (*fn)(webview_t w, void *arg), void *arg);\nextern void *webview_get_window(webview_t w);\nextern void *webview_get_native_handle(webview_t w, webview_native_handle_kind_t kind);\nextern void webview_set_title(webview_t w, const char *title);\nextern void webview_set_size(webview_t w, int width, int height, webview_hint_t hints);\nextern void webview_navigate(webview_t w, const char *url);\nextern void webview_set_html(webview_t w, const char *html);\nextern void webview_init(webview_t w, const char *js);\nextern void webview_eval(webview_t w, const char *js);\nextern void webview_bind(webview_t w, const char *name, void (*fn)(const char *seq, const char *req, void *arg), void *arg);\nextern void webview_unbind(webview_t w, const char *name);\nextern void webview_return(webview_t w, const char *seq, int status, const char *result);"
  }
]