[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [LunaTheFoxgirl]\npatreon: LunaFoxgirlVT"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: Bug Report\ndescription: Report an issue with Inochi Session\ntitle: \"[BUG]\"\nlabels: [\"Bug\", \"Triage\"] \nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: checkboxes\n    id: checkboxes\n    attributes:\n      label: Validations\n      description: Before submitting the bug report, please make sure you do the following\n      options:\n        - label: I have checked for similar bug reports and could not find any.\n          required: true\n        - label: I have tested and confirmed that this is an issue in an official branded build.\n          required: true\n  - type: textarea\n    id: bug-description\n    attributes:\n      label: Describe the bug\n      description: A clear and concise description of what the bug is, and the behavior you expect instead. If you intend to submit a PR for this issue, tell us in the description. Thanks!\n      placeholder: I am doing ... What I expect is ...  What is actually happening is ...\n    validations:\n      required: true\n  - type: textarea\n    id: reproduction\n    attributes:\n      label: Reproduction\n      description: Steps to reproduce the behavior\n      placeholder: |\n        1. Go to '...'\n        2. Click on '...'\n        3. Scroll down to '...'\n        4. See error\n    validations:\n      required: true\n  - type: dropdown\n    id: sys-arch\n    attributes:\n      label: System Architecture\n      options:\n        - x86_64\n        - arm64 / aarch64\n  - type: dropdown\n    id: sys-os\n    attributes:\n      label: Operating System\n      options:\n        - Windows\n        - macOS\n        - Linux\n  - type: input\n    id: version\n    attributes:\n      label: Version\n      description: The version of Inochi Session you are running, or the commit hash if you are running a nightly / main branch build\n  - type: textarea\n    id: logs\n    attributes:\n      label: Logs\n      description: |\n        Optional. If applicable, provide logs using the format below:\n        ````\n        <details>\n        <summary>Click to expand!</summary>\n        ```\n        // paste the log text here\n        ```\n        </details>\n        ````\n  - type: textarea\n    id: additional-context\n    attributes:\n      label: Additional Context\n      description: |\n        Any other context or screenshots about the issue here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\r\ncontact_links:\r\n  - name: Discord Chat\r\n    url: https://discord.com/invite/abnxwN6r9v\r\n    about: Ask questions and discuss with other Inochi2D users in real time.\r\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: Feature request\ndescription: Suggest an idea for Inochi Session\ntitle: \"[Feature Request]\"\nlabels: [\"Enhancement\", \"Triage\"] \nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for your interest in the project and taking the time to fill out this feature request!\n  - type: checkboxes\n    id: checkboxes\n    attributes:\n      label: Validations\n      description: Before submitting the feature request, please make sure you do the following\n      options:\n        - label: I have checked for similar feature requests and could not find any.\n          required: true\n        - label: I have made sure this is not an already-existing feature.\n          required: true\n  - type: textarea\n    id: feature-description\n    attributes:\n      label: Description\n      description: |\n        Clear and concise description of the problem being solved. Please make the reason and usecases as detailed as possible. If you intend to submit a PR for this issue, tell us in the description. Thanks!\n      placeholder: When using Inochi Session, I would like to be able to [goal / wish] so that [benefit].\n    validations:\n      required: true\n  - type: textarea\n    id: suggested-solution\n    attributes:\n      label: Suggested solution\n      description: |\n        A possible implementation to solve the problem.\n    validations:\n      required: true\n  - type: textarea\n    id: alternative\n    attributes:\n      label: Alternative solution\n      description: |\n        A different possible solution to solve the problem.\n  - type: textarea\n    id: additional-context\n    attributes:\n      label: Additional Context\n      description: |\n        Any other context or screenshots about the issue here.\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: 'Build Inochi Session'\nrun-name: 'Build Inochi Session (${{ inputs.variant }})...'\n\non:\n  workflow_call:\n    inputs:\n      target_ref:\n        required: false\n        type: string\n        default: '${{ github.ref_name }}'\n      variant:\n        required: true\n        type: string\n      build_type:\n        required: false\n        type: string\n        default: release\n      generate_version:\n        required: false\n        type: boolean\n        default: false\n      fail_fast:\n        required: false\n        type: boolean\n        default: true\n      do_package:\n        required: false\n        type: boolean\n        default: false\n      postfix:\n        required: false\n        type: string\n        default: ''\n\n\npermissions:\n  contents: write\n\njobs:\n\n  build:\n    runs-on: ${{ matrix.config.os }}\n    strategy:\n      fail-fast: ${{ inputs.fail_fast }}\n      matrix:\n        config:\n          - platform: 'osx'\n            os: 'macos-latest'\n\n          - platform: 'win32'\n            os: windows-latest\n\n          - platform: 'linux'\n            os: ubuntu-latest\n      \n    steps:\n    - uses: actions/checkout@v4\n      with:\n        ref: '${{ inputs.target_ref }}'\n        \n    # Setup D Compiler\n    - uses: dlang-community/setup-dlang@v1.4.0\n      with:\n        compiler: ldc-latest\n\n    - name: 'Preparing build... (Ubuntu)'\n      if: ${{ matrix.config.platform == 'linux' }}\n      run: |\n        sudo apt-get update\n        sudo apt-get install libsdl3-dev libfontconfig-dev\n\n    - name: 'Preparing build... (Windows)'\n      if: ${{ matrix.config.platform == 'win32' }}\n      run: |\n        Remove-Item 'C:/Strawberry' -Recurse\n\n    - name: 'Update version info'\n      if: 'inputs.generate_version'\n      run: |\n        # Build metadata (like version information and icons)\n        dub build --config=update-version\n\n    - name: 'Build (OSX Universal)'\n      if: ${{ matrix.config.platform == 'osx' }}\n      id: osx-build\n      run: |\n        dub build --config=meta\n\n        # First build ARM64 version...\n        echo \"Building arm64 binary...\"\n        dub build --build=${{ inputs.build_type }} --compiler=ldc2 --config=${{ matrix.config.platform }}-${{ inputs.variant }} --arch=arm64-apple-macos\n        mv \"out/Inochi Session.app/Contents/MacOS/inochi-session\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\"\n\n        # Then the X86_64 version...\n        echo \"Building x86_64 binary...\"\n        dub build --build=${{ inputs.build_type }} --compiler=ldc2 --config=${{ matrix.config.platform }}-${{ inputs.variant }} --arch=x86_64-apple-macos\n        mv \"out/Inochi Session.app/Contents/MacOS/inochi-session\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\"\n\n        # Glue them together with lipo\n        echo \"Gluing them together...\"\n        lipo \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\" -output \"out/Inochi Session.app/Contents/MacOS/inochi-session\" -create\n        \n        # Cleanup\n        echo \"Cleaning up...\"\n        rm \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\"\n        \n        # Bundle\n        echo \"Bundling up to app\"\n        ./build-aux/osx/osxbundle.sh\n\n    - name: 'Build (Windows)'\n      if: ${{ matrix.config.platform == 'win32' }}\n      id: win32-build\n      shell: powershell\n      run: |\n        .\\vcvars.ps1\n        dub build --config=meta\n        dub build --build=${{ inputs.build_type }} --compiler=ldc2 --config=${{ matrix.config.platform }}-${{ inputs.variant }}\n\n    - name: 'Build (Linux)'\n      if: ${{ matrix.config.platform == 'linux' }}\n      id: posix-build\n      run: |\n        dub build --config=meta\n        dub build --build=${{ inputs.build_type }} --compiler=ldc2 --config=${{ matrix.config.platform }}-${{ inputs.variant }}\n\n    # TODO: Add signing workflow.\n    # - name: 'Select latest XCode (OSX)'\n    #   if: ${{ startsWith(matrix.config.os, 'macos') }}\n    #   uses: BoundfoxStudios/action-xcode-select@v1\n    # - name: 'Sign and Notarize (OSX)'\n    #   if: ${{ startsWith(matrix.config.os, 'macos') }}\n    #   uses: BoundfoxStudios/action-xcode-notarize@v1.1\n    #   with:\n    #     product-path: 'out/Inochi Session.app'\n\n    - name: 'Make Artifact (Main)'\n      uses: actions/upload-artifact@v4\n      with:\n        name: build-${{ matrix.config.platform }}${{ inputs.postfix }}\n        path: |\n          out/*\n          version.txt\n        retention-days: 1\n\n    - name: Archive Zip\n      uses: thedoctor0/zip-release@main\n      with:\n        type: 'zip'\n        filename: 'inochi-session-${{ matrix.config.platform }}.zip'\n        directory: 'out/'\n        path: '*'\n\n    - name: 'Make Artifact (ZIP)'\n      uses: actions/upload-artifact@v4\n      with:\n        name: build-${{ matrix.config.platform }}-zip${{ inputs.postfix }}\n        path: |\n          out/inochi-session-${{ matrix.config.platform }}.zip\n          version.txt\n        retention-days: 1\n  \n  package-dmg:\n    if: ${{ inputs.do_package == true }}\n    needs: build\n    runs-on: macos-14\n\n    steps:\n    - uses: actions/checkout@v4.1.7\n      with:\n        sparse-checkout:\n          build-aux\n\n    - uses: actions/download-artifact@v4\n      with:\n        name: build-osx${{ inputs.postfix }}\n    \n    - name: 'Install create-dmg...'\n      run: |\n        brew update\n        brew install create-dmg\n\n    - name: 'Build DMG'\n      run: |\n        ./build-aux/osx/gendmg.sh\n\n    - name: Make Artifact\n      uses: actions/upload-artifact@v4\n      with:\n        name: build-osx-dmg${{ inputs.postfix }}\n        path: |\n          out/Install_Inochi_Session.dmg\n          version.txt\n        overwrite: true\n        retention-days: 1\n"
  },
  {
    "path": ".github/workflows/pr-test.yml",
    "content": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\nname: Pull Request Test\n\non:\n  pull_request:\n    branches: [ \"main\" ]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n\n    runs-on: ubuntu-20.04\n\n    steps:\n    - uses: actions/checkout@v4.1.7\n    - uses: dlang-community/setup-dlang@4c99aa991ce7d19dd3064de0a4f2f6b2f152e2d7\n      with:\n        compiler: ldc-latest\n  \n    - name: \"Get build dependencies\"\n      run: |\n        sudo apt install libsdl2-dev libfreetype6-dev\n      \n    - name: \"Clone dependencies & set versions\"\n      run: |\n        git clone https://github.com/Inochi2D/i2d-imgui.git --recurse-submodules\n        git clone https://github.com/Inochi2D/inochi2d.git\n        dub add-local i2d-imgui/ \"0.8.0\"\n        dub add-local inochi2d/ \"0.8.5\"\n\n    - name: 'Build'\n      run: |\n        # Build metadata (like version information and icons)\n        dub build --config=meta\n        \n        # Build the project, with its main file included, without unittests\n        dub build --compiler=ldc2 --build=release --config=linux-full\n    \n    - name: 'Test'\n      run: |\n        dub test --compiler=ldc2 --config=linux-full\n\n    - name: \"Upload Artifacts\"  \n      if: success()\n      uses: actions/upload-artifact@v3\n      with:\n        name: inochi-session\n        path: out/inochi-session"
  },
  {
    "path": ".github/workflows/publish-gh.yml",
    "content": "name: 'Publish to GitHub'\n\npermissions:\n  contents: write\n\non:\n  workflow_call:\n    inputs:\n      tag:\n        required: false\n        type: string\n        default: ${{ github.ref_name }}\n      name:\n        required: false\n        type: string\n        default: ''\n      generate-notes:\n        required: false\n        type: boolean\n        default: false\n      postfix:\n        required: false\n        type: string\n        default: ''\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/download-artifact@v4\n      with:\n        pattern: '*${{ inputs.postfix }}'\n        merge-multiple: true\n\n    - name: 'Release to ${{ inputs.tag }}'\n      uses: softprops/action-gh-release@v2\n      with:\n        name: '${{ inputs.name }}'\n        tag_name: ${{ inputs.tag }}\n        files: |\n          out/inochi-session-linux.zip\n          out/inochi-session-win32.zip\n          out/inochi-session-osx.zip\n          out/Install_Inochi_Session.dmg\n        generate_release_notes: ${{ inputs.generate-notes }}\n"
  },
  {
    "path": ".github/workflows/publish-itch.yml",
    "content": "name: 'Publish to itch.io'\n\non:\n  workflow_call:\n    inputs:\n      postfix:\n        required: false\n        type: string\n        default: ''\n\njobs:\n  publish:\n    continue-on-error: true\n    name: 'Publish'\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        config:\n          - name: \"Windows (ZIP)\"\n            channel: 'windows'\n            artifact: 'build-win32-zip${{ inputs.postfix }}'\n            file: 'inochi-session-win32.zip'\n\n          - name: \"macOS (ZIP)\"\n            channel: 'osx'\n            artifact: 'build-osx-zip${{ inputs.postfix }}'\n            file: 'inochi-session-osx.zip'\n\n          - name: \"macOS (DMG)\"\n            channel: 'osx-dmg'\n            artifact: 'build-osx-dmg${{ inputs.postfix }}'\n            file: 'Install_Inochi_Session.dmg'\n\n          - name: \"Linux\"\n            channel: 'linux'\n            artifact: 'build-linux-zip${{ inputs.postfix }}'\n            file: 'inochi-session-linux.zip'\n    steps:\n    - name: 'Download ${{ matrix.config.artifact }}...'\n      uses: actions/download-artifact@v4\n      with:\n        name: '${{ matrix.config.artifact }}'\n\n\n    - name: 'Publishing ${{ matrix.config.name }} to Itch...'\n      uses: manleydev/butler-publish-itchio-action@master\n      env:\n        BUTLER_CREDENTIALS: ${{ secrets.BUTLER_CREDENTIALS }}\n        CHANNEL: ${{ matrix.config.channel }}\n        ITCH_GAME: inochi-session\n        ITCH_USER: kitsunebi-games\n        VERSION_FILE: version.txt\n        PACKAGE: 'out/${{ matrix.config.file }}'\n"
  },
  {
    "path": ".github/workflows/release-nightly.yml",
    "content": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\nname: Build and Release (Nightly)\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n  workflow_dispatch:\n\n\npermissions:\n  contents: write\n\njobs:\n  build:\n    uses: './.github/workflows/build.yml'\n    with:\n      variant: 'nightly'\n      generate_version: true\n      do_package: true\n      fail_fast: false\n  \n  gh-publish:\n    needs: build\n    uses: './.github/workflows/publish-gh.yml'\n    secrets: inherit\n    with:\n      tag: 'nightly'\n      name: 'Nightly'\n      generate-notes: true\n  \n  # Delete artifacts after use.\n  cleanup:\n    if: 'always()'\n    runs-on: ubuntu-latest\n    needs: [gh-publish]\n    steps:\n    - uses: GeekyEggo/delete-artifact@v5\n      with: \n        name: |\n          *"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\nname: Build and Release\n\non:\n  push:\n    # Push all normally versioned tags\n    tags:\n      - 'v*'\n\npermissions:\n  contents: write\n\njobs:\n\n  # Full Release\n  # This needs \"gh-publish-demo\" due to the fact that\n  # we need to overwrite the artifacts related.\n  build:\n    if: ${{ ! contains(github.ref_name, 'rc') }}\n    uses: './.github/workflows/build.yml'\n    with:\n      target_ref: '${{ github.ref_name }}'\n      variant: 'full'\n      generate_version: true\n      do_package: true\n\n  itch-publish:\n    needs: build\n    uses: './.github/workflows/publish-itch.yml'\n    secrets: inherit\n\n  gh-publish:\n    needs: build\n    uses: './.github/workflows/publish-gh.yml'\n    secrets: inherit\n  \n  # Delete artifacts after use.\n  cleanup:\n    if: 'always()'\n    runs-on: ubuntu-latest\n    needs: [itch-publish, gh-publish]\n    steps:\n    - uses: GeekyEggo/delete-artifact@v5\n      with: \n        name: |\n          *"
  },
  {
    "path": ".gitignore",
    "content": ".dub\ndocs.json\n__dummy.html\ndocs/\n*.exe\n*.pdb\n*.o\n*.obj\n*.lst\n*.res\n\nout/\ndub.selections.json\n__dummy_docs/\n\n# Redub Junk\n.ldc2_cache\n\n# Other Junk\n.DS_Store\n.vscode/"
  },
  {
    "path": "LICENSE",
    "content": "BSD 2-Clause License\n\nCopyright (c) 2020, Inochi2D Project\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "README.md",
    "content": "# Inochi Session\n![image](https://user-images.githubusercontent.com/7032834/181119161-f83e8e57-2f9e-409f-90bd-1b1b9c047bcc.png)\n\n_[Aka (example model)](https://github.com/Inochi2D/example-models#aka) by [seagetch](https://twitter.com/seagetch)_\n\n*Inochi Session is the official tool for using Inochi2D puppets for VTubing.*\n\nThis application is currently under heavy development and isn't ready for production just yet.\n"
  },
  {
    "path": "build-aux/linux/inochi-session.appdata.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<component type=\"desktop\">\n  <id>inochi-session</id>\n  <launchable type=\"desktop-id\">inochi-session.desktop</launchable>\n  <name>Inochi Session</name>\n  <metadata_license>CC0-1.0</metadata_license>\n  <project_license>BSD-2-Clause</project_license>\n  <summary>Tool for using Inochi2D puppets for streaming.</summary>\n  <description>\n    <p>\n      Inochi2D is a framework for realtime 2D puppet animation which can be used for VTubing, \n      game development and digital animation. \n    </p>\n    <p>\n      Inochi Session is a tool that lets you use your Inochi2D models for live streaming.\n    </p>\n  </description>\n  <url type=\"homepage\">https://inochi2d.com</url>\n  <url type=\"help\">https://github.com/Inochi2D/inochi-session</url>\n  <url type=\"bugtracker\">https://github.com/Inochi2D/inochi-session/issues</url>\n  <screenshots>\n    <screenshot type=\"default\">\n      <caption>Title screen</caption>\n      <image>https://user-images.githubusercontent.com/7032834/181119161-f83e8e57-2f9e-409f-90bd-1b1b9c047bcc.png</image>\n    </screenshot>\n  </screenshots>\n  <categories>\n    <category>Graphics</category>\n  </categories>\n</component>"
  },
  {
    "path": "build-aux/linux/inochi-session.desktop",
    "content": "[Desktop Entry]\nName=inochi-session\nExec=inochi-session\nIcon=icon_x256\nType=Application\nCategories=Utility"
  },
  {
    "path": "build-aux/osx/BuildUniversal.sh",
    "content": "# First build ARM64 version...\necho \"Building arm64 binary...\"\ndub build --build=release --config=osx-full --arch=arm64-apple-macos\nmv \"out/Inochi Session.app/Contents/MacOS/inochi-session\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\"\n\n# Then the X86_64 version...\necho \"Building x86_64 binary...\"\ndub build --build=release --config=osx-full --arch=x86_64-apple-macos\nmv \"out/Inochi Session.app/Contents/MacOS/inochi-session\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\"\n\n# Glue them together with lipo\necho \"Gluing them together...\"\nlipo \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\" -output \"out/Inochi Session.app/Contents/MacOS/inochi-session\" -create\n\n# Print some nice info\necho \"Done!\"\nlipo -info \"out/Inochi Session.app/Contents/MacOS/inochi-session\"\n\n# Cleanup and bundle\necho \"Cleaning up...\"\nrm \"out/Inochi Session.app/Contents/MacOS/inochi-session-x86_64\" \"out/Inochi Session.app/Contents/MacOS/inochi-session-arm64\"\n./osxbundle.sh"
  },
  {
    "path": "build-aux/osx/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>CFBundleName</key>\n    <string>Inochi Session</string>\n    <key>CFBundleDisplayName</key>\n    <string>Inochi Session</string>\n    <key>CFBundleIdentifier</key>\n    <string>com.inochi2d.inochi-session</string>\n    <key>CFBundleVersion</key>\n    <string>0.7.4</string>\n    <key>CFBundlePackageType</key>\n    <string>APPL</string>\n    <key>CFBundleSignature</key>\n    <string>inoc</string>\n    <key>CFBundleExecutable</key>\n    <string>inochi-session</string>\n    <key>CFBundleIconFile</key>\n    <string>InochiSession</string>\n    <key>CFBundleDocumentTypes</key>\n    <array>\n      <dict>\n        <key>CFBundleTypeIconFile</key>\n        <string>project.icns</string>\n        <key>CFBundleTypeName</key>\n        <string>Inochi2D Puppet</string>\n        <key>CFBundleTypeRole</key>\n        <string>Editor</string>\n        <key>LSItemContentTypes</key>\n        <array>\n            <string>com.inochi2d.inochi2d.puppet</string>\n        </array>\n      </dict>\n    </array>\n    <key>UTExportedTypeDeclarations</key>\n    <array>\n      <dict>\n        <key>UTTypeIdentifier</key>\n        <string>com.inochi2d.inochi2d.puppet</string>\n        <key>UTTypeReferenceURL</key>\n        <string>https://github.com/Inochi2D/inochi2d/wiki/INP-Data-Interchange-Format</string>\n        <key>UTTypeDescription</key>\n        <string>Inochi2D Puppet</string>\n        <key>UTTypeIconFile</key>\n        <string>puppet.icns</string>\n        <key>UTTypeConformsTo</key>\n        <array>\n          <string>public.data</string>\n        </array>\n        <key>UTTypeTagSpecification</key>\n        <dict>\n          <key>public.filename-extension</key>\n          <array>\n            <string>inp</string>\n          </array>\n        </dict>\n      </dict>\n    </array>\n  </dict>\n</plist>"
  },
  {
    "path": "build-aux/osx/gendmg.sh",
    "content": "DMGTITLE=\"Install Inochi Session\"\nDMGFILENAME=\"Install_Inochi_Session.dmg\"\n\nif [ -d \"out/Inochi Session.app\" ]; then\n    if [ -f \"out/$DMGFILENAME\" ]; then\n        echo \"Removing prior install dmg...\"\n        rm \"out/$DMGFILENAME\"\n    fi\n\n    PREVPWD=$PWD\n    cd out/\n    echo \"Building $DMGFILENAME...\"\n\n    # Create Install Volume directory\n\n    if [ -d \"InstallVolume\" ]; then\n        echo \"Cleaning up old install volume...\"\n        rm -r InstallVolume\n    fi\n\n    mkdir -p InstallVolume\n    cp ../LICENSE LICENSE\n    cp -r \"Inochi Session.app\" \"InstallVolume/Inochi Session.app\"\n    \n    # Downloaded artifact removes executable flag.\n    chmod +x \"InstallVolume/Inochi Session.app/Contents/MacOS/inochi-session\"\n    \n    create-dmg \\\n        --volname \"$DMGTITLE\" \\\n        --volicon \"InochiSession.icns\" \\\n        --background \"../build-aux/osx/dmgbg.png\" \\\n        --window-size 800 600 \\\n        --icon \"Inochi Session.app\" 200 250 \\\n        --hide-extension \"Inochi Session.app\" \\\n        --eula \"LICENSE\" \\\n        --app-drop-link 600 250 \\\n        \"$DMGFILENAME\" InstallVolume/\n\n    echo \"Done! Cleaning up temporaries...\"\n    rm LICENSE\n\n    echo \"DMG generated as $PWD/$DMGFILENAME\"\n    cd $PREVPWD\nelse\n    echo \"Could not find Inochi Session for packaging...\"\nfi\n"
  },
  {
    "path": "build-aux/osx/osxbundle.sh",
    "content": "echo \"Creating directory structure...\"\nLASTPWD=$PWD\n\n# Handle copying all the dylibs to their respective directories\n# As well handle creating our directory structure\ncd out/Inochi\\ Session.app/Contents\n\n# Remove old files\nif [ -d \"Frameworks\" ]; then\n    echo \"Removing files from prior bundle...\"\n    rm -r Frameworks SharedSupport Resources\n    rm Info.plist\nfi\n\n# Create new directories and move dylibs\nmkdir -p Frameworks SharedSupport Resources Resources/i18n\nmv MacOS/libSDL2-2.0.dylib Frameworks/libSDL2.dylib\nmv -n MacOS/*.dylib Frameworks\n\n# Move back to where we were\ncd $LASTPWD\n\necho \"Setting up file structure...\"\n\n# Copy info plist and icon\ncp build-aux/osx/Info.plist out/Inochi\\ Session.app/Contents/\n\n# Move any translation files in if any.\nmv -n out/*.mo out/Inochi\\ Session.app/Contents/Resources/i18n/\n\n# Copy license info to SharedSupport\ncp res/licenses/*-LICENSE out/Inochi\\ Session.app/Contents/SharedSupport/\ncp LICENSE out/Inochi\\ Session.app/Contents/SharedSupport/LICENSE\n\n\n# Create icons dir\n# TODO: check if dir exists, skip this step if it does\nif [ ! -d \"out/InochiCreator.icns\" ]; then\n    iconutil -c icns -o out/InochiSession.icns build-aux/osx/Inochi-Session.iconset\nelse\n    echo \"Icons already exist, skipping...\"\nfi\n\necho \"Applying Icon...\"\ncp out/InochiSession.icns out/Inochi\\ Session.app/Contents/Resources/InochiSession.icns \n\necho \"Cleaning up...\"\nfind out/Inochi\\ Session.app/Contents/MacOS -type f ! -name \"inochi-session\" -delete\n\necho \"Done!\"\n"
  },
  {
    "path": "build-aux/windows/inochi-session.rc",
    "content": "#include <windows.h>\n#include \"version.h\"\n\nIDI_ICON1          ICON           \"icon.ico\"\n\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION     VER_FILEVERSION\nPRODUCTVERSION  VER_PRODUCTVERSION\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"040904E4\"\n        BEGIN\n            VALUE \"CompanyName\",        VER_COMPANYNAME_STR\n            VALUE \"FileDescription\",    VER_FILEDESCRIPTION_STR\n            VALUE \"FileVersion\",        VER_FILEVERSION_STR\n            VALUE \"InternalName\",       VER_INTERNALNAME_STR\n            VALUE \"LegalCopyright\",     VER_LEGALCOPYRIGHT_STR\n            VALUE \"OriginalFilename\",   VER_ORIGINALFILENAME_STR\n            VALUE \"ProductName\",        VER_PRODUCTNAME_STR\n            VALUE \"ProductVersion\",     VER_PRODUCTVERSION_STR\n        END\n    END\n\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x409, 1252\n    END\nEND"
  },
  {
    "path": "build-aux/windows/version.h",
    "content": "#ifndef VERSION_H\n#define VERSION_H\n\n#define VER_FILEVERSION 0,8,1,0\n#define VER_FILEVERSION_STR \"0.8.1\\0\"\n\n#define VER_PRODUCTVERSION          0,8,1,0\n#define VER_PRODUCTVERSION_STR      \"0.8.1\\0\"\n\n#define VER_COMPANYNAME_STR         \"Inochi2D Project\"\n#define VER_FILEDESCRIPTION_STR     \"Inochi Session\"\n#define VER_INTERNALNAME_STR        \"inochi-session\"\n#define VER_LEGALCOPYRIGHT_STR      \"Copyright © 2022-2023 Inochi2D Project\"\n#define VER_ORIGINALFILENAME_STR    \"inochi-session.exe\"\n#define VER_PRODUCTNAME_STR         \"Inochi Session\"\n\n#define VER_COMPANYDOMAIN_STR       \"inochi2d.com\"\n\n#endif // VERSION_H\n"
  },
  {
    "path": "dub.sdl",
    "content": "name \"inochi-session\"\ndescription \"App that allows you to stream with Inochi2D puppets\"\nauthors \"Inochi2D Project\"\ncopyright \"Copyright © 2021, Inochi2D Project\"\nlicense \"BSD 2-clause\"\n\ndependency \"facetrack-d\" version=\"~>0.8.0\"\ndependency \"lumars\" version=\"~>1.6.1\"\n\ndependency \"inochi2d\" path=\"../inochi2d\"\ndependency \"inui\" path=\"../inui\"\n\ntargetPath \"out/\"\nworkingDirectory \"out/\"\ncopyFiles \"res/licenses/*\"\n\ndflags \"-mscrtlib=msvcrt\" platform=\"windows-ldc\"\nlflags \"-rpath=$$ORIGIN\" platform=\"linux\"\n\nbuildRequirements \"allowWarnings\"\n\nstringImportPaths \"res\"\n\n// Uncomment following lines to enable JINS MEME Logger module.\n//versions \"JML\"\n//subConfiguration \"facetrack-d\" \"jml\"\n\n//\n// CONFIGURATIONS\n//\nconfiguration \"barebones\" {\n\tplatforms \"linux\"\n\ttargetType \"executable\"\n}\n\n\n// Official build configurations.\n// Do not package your compilation of Inochi Creator with these configurations\n// unless you have prior permission from the Inochi2D project.\n\nconfiguration \"linux-full\" {\n\tplatforms \"linux\"\n\n\ttargetType \"executable\"\n\tversions \"InBranding\"\n}\n\nconfiguration \"osx-full\" {\n\tplatforms \"osx\"\n\ttargetType \"executable\"\n\ttargetPath \"out/Inochi Session.app/Contents/MacOS\"\n\tversions \"InBranding\"\n\n\tsubConfiguration \"i2d-imgui\" \"dynamic_dynamicCRT\"\n\tlflags \"-rpath\" \"@executable_path/../Frameworks\" \"-rpath\" \"@executable_path/.\"\n}\n\nconfiguration \"win32-full\" {\n\tplatforms \"windows\"\n\ttargetType \"executable\"\n\tversions \"InBranding\"\n\t\n\tdependency \"bindbc-spout2\" version=\"~>0.1.1\"\n\n\tlflags \"/SUBSYSTEM:windows\" \"/ENTRY:mainCRTStartup\" platform=\"window-dmd\"\n\tsourceFiles \"build-aux\\\\windows\\\\inochi-session.res\"\n}\n\n// Linux nightly build\nconfiguration \"linux-nightly\" {\n\n\tplatforms \"linux\"\n\ttargetType \"executable\"\n\tsubConfiguration \"i2d-imgui\" \"static_dynamicCRT\"\n\tversions \"InNightly\"\n\t\n\tdependency \"dportals\" version=\"~>0.1.0\"\n}\n\n// macOS nightly build\nconfiguration \"osx-nightly\" {\n\tplatforms \"osx\"\n\ttargetType \"executable\"\n\n\ttargetPath \"out/Inochi Session.app/Contents/MacOS\"\n\n\tsubConfiguration \"i2d-imgui\" \"dynamic_dynamicCRT\"\n\tdflags \"-force-dwarf-frame-section=false\"\n\tlflags \"-rpath\" \"@executable_path/../Frameworks\" \"-rpath\" \"@executable_path/.\"\n\n\tversions \"InNightly\"\n}\n\n// Windows nightly build\nconfiguration \"win32-nightly\" {\n\tplatforms \"windows\"\n\ttargetType \"executable\"\n\tversions \"InBranding\" \"InNightly\"\n\t\n\tdependency \"bindbc-spout2\" version=\"~>0.1.1\"\n\n\tlflags \"/SUBSYSTEM:windows\" \"/ENTRY:mainCRTStartup\" platform=\"window-dmd\"\n\tsourceFiles \"build-aux\\\\windows\\\\inochi-session.res\"\n}\n\n\n// Meta configurations\n\nconfiguration \"update-version\" {\n\ttargetType \"none\"\n\tpreGenerateCommands \"dub run gitver -- --prefix INS --file source/session/ver.d --mod session.ver --appname \\\"Inochi Session\\\" --itchfile res/version.txt\"\n}\n\nconfiguration \"meta\" {\n\ttargetType \"none\"\n\tpreGenerateCommands \"rc.exe /v build-aux\\\\windows\\\\inochi-session.rc\" platform=\"windows\"\n}"
  },
  {
    "path": "genpot.sh",
    "content": "#!/bin/sh\nfind . -iname \"*.d\" | xargs xgettext --from-code=UTF-8 -o tl/template.pot -c --keyword=_ --keyword=__"
  },
  {
    "path": "gentl.sh",
    "content": "mkdir -p out/\n\nif [ -n `$(find tl/ -name \"*.po\" 2>/dev/null)` ]\nthen\n    echo \"No translations, skipping...\"\nelse\n    for f in tl/*.po; do\n        msgfmt -o \"out/$(basename -- \"$f\" .po).mo\" -- \"$f\" \n    done\nfi"
  },
  {
    "path": "imgui.ini",
    "content": "[Window][WindowOverViewport_11111111]\nPos=0,0\nSize=1065,754\nCollapsed=0\n\n[Window][Debug##Default]\nPos=60,60\nSize=400,400\nCollapsed=0\n\n[Docking][Data]\nDockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=1065,754 CentralNode=1 Selected=0xA9D0F322\n\n"
  },
  {
    "path": "res/licenses/LICENSE-FreeType",
    "content": "                    The FreeType Project LICENSE\n                    ----------------------------\n\n                            2006-Jan-27\n\n                    Copyright 1996-2002, 2006 by\n          David Turner, Robert Wilhelm, and Werner Lemberg\n\n\n\nIntroduction\n============\n\n  The FreeType  Project is distributed in  several archive packages;\n  some of them may contain, in addition to the FreeType font engine,\n  various tools and  contributions which rely on, or  relate to, the\n  FreeType Project.\n\n  This  license applies  to all  files found  in such  packages, and\n  which do not  fall under their own explicit  license.  The license\n  affects  thus  the  FreeType   font  engine,  the  test  programs,\n  documentation and makefiles, at the very least.\n\n  This  license   was  inspired  by  the  BSD,   Artistic,  and  IJG\n  (Independent JPEG  Group) licenses, which  all encourage inclusion\n  and  use of  free  software in  commercial  and freeware  products\n  alike.  As a consequence, its main points are that:\n\n    o We don't promise that this software works. However, we will be\n      interested in any kind of bug reports. (`as is' distribution)\n\n    o You can  use this software for whatever you  want, in parts or\n      full form, without having to pay us. (`royalty-free' usage)\n\n    o You may not pretend that  you wrote this software.  If you use\n      it, or  only parts of it,  in a program,  you must acknowledge\n      somewhere  in  your  documentation  that  you  have  used  the\n      FreeType code. (`credits')\n\n  We  specifically  permit  and  encourage  the  inclusion  of  this\n  software, with  or without modifications,  in commercial products.\n  We  disclaim  all warranties  covering  The  FreeType Project  and\n  assume no liability related to The FreeType Project.\n\n\n  Finally,  many  people  asked  us  for  a  preferred  form  for  a\n  credit/disclaimer to use in compliance with this license.  We thus\n  encourage you to use the following text:\n\n   \"\"\"\n    Portions of this software are copyright © <year> The FreeType\n    Project (www.freetype.org).  All rights reserved.\n   \"\"\"\n\n  Please replace <year> with the value from the FreeType version you\n  actually use.\n\n\nLegal Terms\n===========\n\n0. Definitions\n--------------\n\n  Throughout this license,  the terms `package', `FreeType Project',\n  and  `FreeType  archive' refer  to  the  set  of files  originally\n  distributed  by the  authors  (David Turner,  Robert Wilhelm,  and\n  Werner Lemberg) as the `FreeType Project', be they named as alpha,\n  beta or final release.\n\n  `You' refers to  the licensee, or person using  the project, where\n  `using' is a generic term including compiling the project's source\n  code as  well as linking it  to form a  `program' or `executable'.\n  This  program is  referred to  as  `a program  using the  FreeType\n  engine'.\n\n  This  license applies  to all  files distributed  in  the original\n  FreeType  Project,   including  all  source   code,  binaries  and\n  documentation,  unless  otherwise  stated   in  the  file  in  its\n  original, unmodified form as  distributed in the original archive.\n  If you are  unsure whether or not a particular  file is covered by\n  this license, you must contact us to verify this.\n\n  The FreeType  Project is copyright (C) 1996-2000  by David Turner,\n  Robert Wilhelm, and Werner Lemberg.  All rights reserved except as\n  specified below.\n\n1. No Warranty\n--------------\n\n  THE FREETYPE PROJECT  IS PROVIDED `AS IS' WITHOUT  WARRANTY OF ANY\n  KIND, EITHER  EXPRESS OR IMPLIED,  INCLUDING, BUT NOT  LIMITED TO,\n  WARRANTIES  OF  MERCHANTABILITY   AND  FITNESS  FOR  A  PARTICULAR\n  PURPOSE.  IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS\n  BE LIABLE  FOR ANY DAMAGES CAUSED  BY THE USE OR  THE INABILITY TO\n  USE, OF THE FREETYPE PROJECT.\n\n2. Redistribution\n-----------------\n\n  This  license  grants  a  worldwide, royalty-free,  perpetual  and\n  irrevocable right  and license to use,  execute, perform, compile,\n  display,  copy,   create  derivative  works   of,  distribute  and\n  sublicense the  FreeType Project (in  both source and  object code\n  forms)  and  derivative works  thereof  for  any  purpose; and  to\n  authorize others  to exercise  some or all  of the  rights granted\n  herein, subject to the following conditions:\n\n    o Redistribution of  source code  must retain this  license file\n      (`FTL.TXT') unaltered; any  additions, deletions or changes to\n      the original  files must be clearly  indicated in accompanying\n      documentation.   The  copyright   notices  of  the  unaltered,\n      original  files must  be  preserved in  all  copies of  source\n      files.\n\n    o Redistribution in binary form must provide a  disclaimer  that\n      states  that  the software is based in part of the work of the\n      FreeType Team,  in  the  distribution  documentation.  We also\n      encourage you to put an URL to the FreeType web page  in  your\n      documentation, though this isn't mandatory.\n\n  These conditions  apply to any  software derived from or  based on\n  the FreeType Project,  not just the unmodified files.   If you use\n  our work, you  must acknowledge us.  However, no  fee need be paid\n  to us.\n\n3. Advertising\n--------------\n\n  Neither the  FreeType authors and  contributors nor you  shall use\n  the name of the  other for commercial, advertising, or promotional\n  purposes without specific prior written permission.\n\n  We suggest,  but do not require, that  you use one or  more of the\n  following phrases to refer  to this software in your documentation\n  or advertising  materials: `FreeType Project',  `FreeType Engine',\n  `FreeType library', or `FreeType Distribution'.\n\n  As  you have  not signed  this license,  you are  not  required to\n  accept  it.   However,  as  the FreeType  Project  is  copyrighted\n  material, only  this license, or  another one contracted  with the\n  authors, grants you  the right to use, distribute,  and modify it.\n  Therefore,  by  using,  distributing,  or modifying  the  FreeType\n  Project, you indicate that you understand and accept all the terms\n  of this license.\n\n4. Contacts\n-----------\n\n  There are two mailing lists related to FreeType:\n\n    o freetype@nongnu.org\n\n      Discusses general use and applications of FreeType, as well as\n      future and  wanted additions to the  library and distribution.\n      If  you are looking  for support,  start in  this list  if you\n      haven't found anything to help you in the documentation.\n\n    o freetype-devel@nongnu.org\n\n      Discusses bugs,  as well  as engine internals,  design issues,\n      specific licenses, porting, etc.\n\n  Our home page can be found at\n\n    https://www.freetype.org\n\n\n--- end of FTL.TXT ---\n"
  },
  {
    "path": "res/licenses/LICENSE-Lua",
    "content": "Copyright © 1994–2021 Lua.org, PUC-Rio.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. "
  },
  {
    "path": "res/licenses/LICENSE-Spout2",
    "content": "BSD 2-Clause License\n\nCopyright (c) 2020, Lynn Jarvis\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "res/licenses/LICENSE-imgui",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014-2022 Omar Cornut\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."
  },
  {
    "path": "res/shaders/batch.frag",
    "content": "#version 330\nin vec2 texUVs;\nin vec4 exColor;\nlayout(location = 0) out vec4 outAlbedo;\nlayout(location = 1) out vec4 outEmission;\nlayout(location = 2) out vec4 outBump;\n\nuniform sampler2D tex;\n\nvoid main() {\n    vec2 texSize = vec2(textureSize(tex, 0));\n    outAlbedo = texture(tex, texUVs/texSize) * exColor;\n    outEmission = texture(tex, texUVs/texSize) * 0.5;\n    outBump = vec4(0.5, 0.5, 1, 1);\n}"
  },
  {
    "path": "res/shaders/batch.vert",
    "content": "#version 330\nuniform mat4 vp;\nlayout(location = 0) in vec2 verts;\nlayout(location = 1) in vec2 uvs;\nlayout(location = 2) in vec4 color;\n\nout vec2 texUVs;\nout vec4 exColor;\n\nvoid main() {\n    gl_Position = vp * vec4(verts.x, verts.y, 0, 1);\n    texUVs = uvs;\n    exColor = color;\n}"
  },
  {
    "path": "res/style.css",
    "content": ".scene {\n    width: 100%;\n    height: 100%;\n}"
  },
  {
    "path": "res/version.txt",
    "content": "0.8.7"
  },
  {
    "path": "source/app.d",
    "content": "module app;\nimport session;\nimport inui;\n\nvoid main(string[] args) {\n    AppInfo info = {\n        name: \"Inochi Session\",\n        author: \"Inochi2D Project\",\n        id: \"com.inochi2d.inochi-session\",\n        version_: import(\"version.txt\"),\n    };\n\n    Application app = new Application(info);\n    app.stylesheet = StyleSheet.parse(import(\"style.css\"));\n    \n    Window window = (new Window(app.appInfo.name, 640, 480))\n        .resizable(true)\n        .vibrancy(SystemVibrancy.vivid);\n    \n    window.view.addWidget(new Scene());\n    app.run(window, args);\n}"
  },
  {
    "path": "source/inochi2d/nio/puppet.d",
    "content": "module inochi2d.nio.puppet;\nimport inochi2d;\nimport niobium;\nimport numem;\nimport nulib.collections;\nimport nulib.math : min, max;\n\n/**\n    A niobium renderered puppet.\n*/\nclass NioPuppet : NuRefCounted {\nprivate:\n@nogc:\n\n    // Puppet info\n    Puppet          puppet_;\n\n    // Render handles\n    NioDevice       device_;\n    NioBuffer       vtx_;\n    NioBuffer       idx_;\n    NioTexture[]    tex_;\n\n    // Creates the puppet and its associated buffers.\n    void createPuppet(string file) {\n        this.puppet_ = assumeNoThrowNoGC(&ins_puppet_load_pinned, file);\n        this.tex_ = nu_malloca!NioTexture(puppet_.textureCache.cache.length);\n        foreach(i, ref Texture texture; puppet_.textureCache.cache) {\n            tex_[i] = device_.createTexture(NioTextureDescriptor(\n                type: NioTextureType.type2D,\n                format: NioPixelFormat.rgba8UnormSRGB, \n                storage: NioStorageMode.privateStorage,\n                usage: NioTextureUsage.transfer | NioTextureUsage.sampled,\n                width: texture.width,\n                height: texture.height,\n            )).upload(NioRegion3D(0, 0, 0, texture.width, texture.height, 1), 0, 0, texture.pixels, 0);\n        }\n\n        // NOTE:    We create the initial buffers here,\n        //          the buffer sizes are not known until an update\n        //          has occured, so we do a 0 ms update.\n        assumeNoThrowNoGC(&ins_puppet_update_pinned, puppet_, 0);\n\n        size_t vtxSize = puppet.drawList.vertices.length * VtxData.sizeof;\n        size_t idxSize = puppet.drawList.indices.length * uint.sizeof;\n        vtx_ = device_.createBuffer(NioBufferDescriptor(\n            storage: NioStorageMode.privateStorage,\n            usage: NioBufferUsage.transfer | NioBufferUsage.vertexBuffer,\n            size: cast(uint)vtxSize\n        ));\n        idx_ = device_.createBuffer(NioBufferDescriptor(\n            storage: NioStorageMode.privateStorage,\n            usage: NioBufferUsage.transfer | NioBufferUsage.indexBuffer,\n            size: cast(uint)idxSize\n        ));\n    }\n\n    // Resizes the vertex and index buffers.\n    void resizeBuffers() {\n        size_t vtxSize = puppet.drawList.vertices.length * VtxData.sizeof;\n        size_t idxSize = puppet.drawList.indices.length * uint.sizeof;\n\n        if (vtxSize > vtx_.size) {\n            vtx_.release();\n            vtx_ = device_.createBuffer(NioBufferDescriptor(\n                storage: NioStorageMode.privateStorage,\n                usage: NioBufferUsage.transfer | NioBufferUsage.vertexBuffer,\n                size: cast(uint)vtxSize\n            ));\n        }\n\n        if (idxSize > idx_.size) {\n            idx_.release();\n            idx_ = device_.createBuffer(NioBufferDescriptor(\n                storage: NioStorageMode.privateStorage,\n                usage: NioBufferUsage.transfer | NioBufferUsage.indexBuffer,\n                size: cast(uint)idxSize\n            ));\n        }\n    }\n\npublic:\n    \n    /**\n        The underlying Inochi2D Puppet\n    */\n    @property Puppet puppet() => puppet_;\n\n    /**\n        The loaded textures of the puppet.\n    */\n    @property NioTexture[] textures() => tex_;\n\n    /**\n        Vertex data of the puppet.\n    */\n    @property VtxData[] vertices() => puppet.drawList.vertices;\n\n    /**\n        The puppet's vertex buffer.\n    */\n    @property NioBuffer vertexBuffer() => vtx_;\n\n    /**\n        Index data of the puppet.\n    */\n    @property uint[] indices() => puppet.drawList.indices;\n\n    /**\n        The puppet's index buffer.\n    */\n    @property NioBuffer indexBuffer() => idx_;\n\n    /**\n        Draw commands of the puppet.\n    */\n    @property DrawCmd[] commands() => puppet.drawList.commands;\n\n    /**\n        Total size of the puppet's buffers.\n    */\n    @property size_t totalBufferSize() => vtx_.size + idx_.size;\n\n\n    // Destructor\n    ~this() {\n        assumeNoThrowNoGC(&ins_puppet_unload_pinned, puppet);\n        if (vtx_) vtx_.release();\n        if (idx_) idx_.release();\n        foreach(ref NioTexture texture; tex_)\n            texture.release();\n        nu_freea(tex_);\n    }\n\n    /**\n        Loads a puppet.\n    */\n    this(NioDevice device, string file) {\n        this.device_ = device;\n        this.createPuppet(file);\n    }\n\n    /**\n        Updates the puppet and resizes vertex and index buffers if needed.\n\n        Params:\n            delta = Time since last frame.\n    */\n    void update(float delta) {\n        assumeNoThrowNoGC(&ins_puppet_update_pinned, puppet_, delta);\n        this.resizeBuffers();\n    }\n}\n\nprivate:\n\nextern(C) void ins_puppet_update_pinned(Puppet puppet, float delta) {\n    puppet.update(delta);\n    puppet.draw(delta);\n}\n\nextern(C) Puppet ins_puppet_load_pinned(string file) {\n    import core.memory : GC;\n\n    auto puppet_ = inLoadPuppet(file);\n    GC.addRoot(cast(void*)puppet_);\n    return puppet_;\n}\n\nextern(C) void ins_puppet_unload_pinned(Puppet puppet) {\n    import core.memory : GC;\n\n    GC.removeRoot(cast(void*)puppet);\n}"
  },
  {
    "path": "source/inochi2d/nio/scene.d",
    "content": "module inochi2d.nio.scene;\nimport inochi2d.nio.staging;\nimport inochi2d.nio.puppet;\nimport inochi2d;\nimport niobium;\nimport numem;\nimport nulib.collections;\nimport nulib.math : min, max;\n\n/**\n    An Inochi2D Scene hosted by Niobium.\n*/\nclass NioScene {\nprivate:\n@nogc:\n    NioDevice                   device_;\n    NioCommandQueue             queue_;\n    weak_vector!NioPuppet       puppets_;\n\n    /// Render state\n    NioStagingBuffer            staging_;\n    NioTexture                  maskTarget_;\n    NioTexture[6][]             renderTargets_;\n\n    /// Updates the puppets and their vertex data.\n    void updatePuppets(NioCommandBuffer cmdbuffer, float delta) {\n\n        // 1. Update the staging buffer's size.\n        size_t totalBufferSize = 0;\n        foreach(ref NioPuppet puppet; puppets_[]) {\n            puppet.update(delta);\n            totalBufferSize += puppet.totalBufferSize;\n        }\n        \n        if (totalBufferSize > staging_.size)\n            staging_.resize(totalBufferSize);\n\n        // Then fill the staging buffer and enqueue transfer commands.\n        auto cmds = cmdbuffer.beginTransferPass();\n            cmds.insertBarrier(NioPipelineStage.transfer, NioPipelineStage.all);\n            \n            size_t vtxStart = 0;\n            foreach(i, ref NioPuppet puppet; puppets_[]) {\n                size_t vtxEnd = staging_.upload(vtxStart, cast(void[])puppet.vertices);\n                size_t idxEnd = staging_.upload(vtxEnd, cast(void[])puppet.indices);\n\n                cmds.copy(\n                    NioBufferSrcInfo(\n                        buffer: staging_.buffer, \n                        offset: cast(uint)vtxStart,\n                        length: cast(uint)(vtxEnd-vtxStart)\n                    ), \n                    NioBufferDstInfo(\n                        buffer: puppet.vertexBuffer,\n                        offset: 0,\n                    )\n                );\n                cmds.copy(\n                    NioBufferSrcInfo(\n                        buffer: staging_.buffer, \n                        offset: cast(uint)vtxEnd,\n                        length: cast(uint)(idxEnd-vtxEnd)\n                    ), \n                    NioBufferDstInfo(\n                        buffer: puppet.indexBuffer,\n                        offset: 0,\n                    )\n                );\n                vtxStart = idxEnd;\n            }\n        cmds.endEncoding();\n    }\n\n    /// Function which draws an individual puppet into the scene.\n    void drawPuppet(NioPuppet puppet) {\n\n    }\n    \npublic:\n    \n    /**\n        The Niobium device being used to render the scene.\n    */\n    @property NioDevice device() => device_;\n\n    /// Destructor\n    ~this() {\n        queue_.release();\n        staging_.release();\n    }\n\n    /// Constructor\n    this(NioDevice device) {\n        this.device_ = device;\n        this.queue_ = device.createQueue(NioCommandQueueDescriptor(32));\n        this.staging_ = nogc_new!NioStagingBuffer(device_);\n    }\n\n    /**\n        Updates all of the puppets currently active in this scene,\n        preparing all the puppets for rendering a frame.\n\n        Params:\n            delta = The time since the last frame.\n    */\n    void update(float delta) {\n        NioCommandBuffer cmdbuffer = queue_.fetch();\n            this.updatePuppets(cmdbuffer, delta);\n            foreach(ref NioPuppet puppet; puppets_) {\n                this.drawPuppet(puppet);\n            }\n        queue_.commit(cmdbuffer);\n        cmdbuffer.await();\n        cmdbuffer.release();\n    }\n\n    /**\n        Blits the scene to the given target texture.\n\n        Notes:\n            This can be called multiple times with minimal overhead,\n            as the internal drawing is done in $(D update).\n\n        Params:\n            target = The target to render the scene to.\n    */\n    void blit(NioTexture target) {\n\n    }\n}"
  },
  {
    "path": "source/inochi2d/nio/staging.d",
    "content": "module inochi2d.nio.staging;\nimport nulib.collections;\nimport niobium;\nimport numem;\n\n/**\n    A managed staging buffer.\n*/\nclass NioStagingBuffer : NuRefCounted {\nprivate:\n@nogc:\n    NioDevice                   device_;\n    NioBuffer                   buffer_;\n    size_t                      alignment_;\n\n    /// Creates initial 32 mb buffer.\n    void createBuffer() {\n        buffer_ = device_.createBuffer(NioBufferDescriptor(\n            storage: NioStorageMode.sharedStorage,\n            usage: NioBufferUsage.transfer,\n            size: 33_554_432\n        ));\n    }\n\npublic:\n\n    /**\n        The underlying staging buffer.\n    */\n    @property NioBuffer buffer() => buffer_;\n\n    /**\n        Alignment of allocations in the buffer.\n    */\n    @property size_t alignment() => alignment_;\n\n    /**\n        Size of the buffer.\n    */\n    @property size_t size() => buffer_.size();\n\n    // Destructor\n    ~this() {\n        buffer_.release();\n    }\n\n    /**\n        Creates a new managed staging buffer.\n\n        Params:\n            device =    The device that owns the staging buffer.\n            alignment = The increments that the staging buffer will grow.\n    */\n    this(NioDevice device, size_t alignment = 33_554_432) {\n        this.device_ = device;\n        this.alignment_ = alignment;\n        this.createBuffer();\n    }\n\n\n    /**\n        Resizes the buffer.\n\n        Params:\n            newSize =   The new size to request from the memory pool.\n\n        Notes:\n            The size will be aligned to $(D alignment).\n    */\n    void resize(size_t newSize) {\n        if (newSize > buffer_.size) {\n            buffer_ = device_.createBuffer(NioBufferDescriptor(\n                storage: NioStorageMode.sharedStorage,\n                usage: NioBufferUsage.transfer,\n                size: cast(uint)nu_alignup(newSize, alignment_)\n            ));\n        }\n    }\n\n    /**\n        Uploads data to the buffer at the given offset.\n\n        Params:\n            offset =    Offset into the staging buffer to upload to.\n            data =      The data to upload.\n        \n        Returns:\n            The ending offset of the upload.\n    */\n    ptrdiff_t upload(size_t offset, void[] data) {\n        if (offset+data.length > this.size)\n            return -1;\n\n        if (auto mapped = buffer_.map()) {\n            mapped[offset..offset+data.length] = data[0..$];\n            buffer_.unmap();\n        }\n        return offset+data.length;\n    }\n}"
  },
  {
    "path": "source/session/package.d",
    "content": "module session;\n\npublic import session.widgets;"
  },
  {
    "path": "source/session/widgets/package.d",
    "content": "module session.widgets;\n\npublic import session.widgets.scene;"
  },
  {
    "path": "source/session/widgets/scene.d",
    "content": "module session.widgets.scene;\nimport inui.widgets;\nimport inui.app;\nimport inochi2d;\n\nimport std.stdio : writeln;\nimport std.file : exists;\nimport inui.core.msgbox;\n\n/**\n    The Inochi2D Scene\n*/\nclass Scene : View {\nprivate:\n    Puppet[] puppets;\n\nprotected:\n\n    override\n    void onDocked(View to) { }\n\npublic:\n\n    /**\n        Whether the view is \"open\" and being rendered.\n    */\n    override @property bool isOpen() => true;\n\n    this() { \n        super(\"in_scene\", \"Scene\");\n        this.styleClass = \"scene\";\n    }\n}\n"
  },
  {
    "path": "tl/placeholder.txt",
    "content": "This placeholder exists just so that it's present on GitHub"
  },
  {
    "path": "tl/template.pot",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"Report-Msgid-Bugs-To: \\n\"\n\"POT-Creation-Date: 2022-07-27 00:24+0200\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"Language: \\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n#: source/session/framesend.d:31\nmsgid \"\"\n\"Could not start texture sharing, it will be disabled. Is the library missing?\"\nmsgstr \"\"\n\n#: source/session/framesend.d:32\nmsgid \"Frame-sending started successfully!\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:88\nmsgid \"Reset\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:92\nmsgid \"Not tracked\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:107\nmsgid \"X\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:112\nmsgid \"Y\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:117\nmsgid \"Z\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:122\nmsgid \"Roll\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:127\nmsgid \"Pitch\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:132\nmsgid \"Yaw\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:151\nmsgid \"Inverse\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:153\nmsgid \"Dampen\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:156\nmsgid \"Tracking In\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:183\nmsgid \"Tracking Out\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:198\nmsgid \"Refresh\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:205\nmsgid \"Save to File\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:225\nmsgid \"No settings available.\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:230\nmsgid \"No puppet selected\"\nmsgstr \"\"\n\n#: source/session/panels/tracking.d:235\nmsgid \"Tracking\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:352\n#, c-format\nmsgid \"%s (X)\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:355\n#, c-format\nmsgid \"%s (Y)\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:358\n#, c-format\nmsgid \"%s (Z)\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:361\n#, c-format\nmsgid \"%s (Roll)\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:364\n#, c-format\nmsgid \"%s (Pitch)\"\nmsgstr \"\"\n\n#: source/session/tracking/package.d:367\n#, c-format\nmsgid \"%s (Yaw)\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:46 source/session/windows/spaceedit.d:22\n#: source/session/windows/spaceedit.d:181\nmsgid \"Error\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:75\nmsgid \"File\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:77\nmsgid \"Exit\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:84\nmsgid \"View\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:86\nmsgid \"Panels\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:97\nmsgid \"Configuration\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:99 source/session/windows/spaceedit.d:213\nmsgid \"Virtual Spaces\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:106\nmsgid \"Plugins\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:112\nmsgid \"Help\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:113\nmsgid \"About\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:122\nmsgid \"Double-click to show/hide UI\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:126 source/session/windows/main.d:128\nmsgid \"Donate\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:164\nmsgid \"Inochi Session\"\nmsgstr \"\"\n\n#: source/session/windows/main.d:165\nmsgid \"\"\n\"THIS IS BETA SOFTWARE\\n\"\n\"\\n\"\n\"This software is incomplete, please lower your expectations.\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:55 source/session/windows/spaceedit.d:70\nmsgid \"Delete\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:130\n#: source/session/windows/spaceedit.d:195\nmsgid \"\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:138\nmsgid \"No zone selected for editing...\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:141\nmsgid \"Zone Name\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:150\nmsgid \"Unset\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:175\nmsgid \"Save Changes\"\nmsgstr \"\"\n\n#: source/session/windows/spaceedit.d:206\nmsgid \"Save\"\nmsgstr \"\"\n"
  },
  {
    "path": "vcvars.ps1",
    "content": "function Invoke-VSDevEnvironment {\n    $vswhere = \"${env:ProgramFiles(x86)}\\Microsoft Visual Studio\\Installer\\vswhere.exe\"\n            $installationPath = & $vswhere -prerelease -legacy -latest -property installationPath\n            $Command = Join-Path $installationPath \"Common7\\Tools\\vsdevcmd.bat\"\n        & \"${env:COMSPEC}\" /s /c \"`\"$Command`\" -no_logo && set\" | Foreach-Object {\n                if ($_ -match '^([^=]+)=(.*)') {\n                    [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])\n                }\n            }\n}\nInvoke-VSDevEnvironment"
  }
]