[
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\n\ncontact_links:\n  - name: AppsFlyer Support (Customer Assistant Chatbot)\n    url: https://support.appsflyer.com/hc/en-us/articles/23583984402193-Using-the-Customer-Assistant-Chatbot\n    about: For the fastest and most effective support, please contact the AppsFlyer support team using the Customer Assistant Chatbot. \n"
  },
  {
    "path": ".github/workflows/Scripts/checkJira.sh",
    "content": "JIRA_TOKEN=$1\nJIRA_FIXED_VERSION=$2\n\nfixed_version_found=false\ncurl -X GET https://appsflyer.atlassian.net/rest/api/3/project/11723/versions --user $JIRA_TOKEN | jq -r '.[] | .name+\"\"+(.id | tostring)' | while read version ; do\nif [[ \"$version\" == *\"$JIRA_FIXED_VERSION\"* ]] ;then\n    echo \"$JIRA_FIXED_VERSION Found!\"\n    fixed_version_found=true\n    version_id=${version#\"$JIRA_FIXED_VERSION\"}\n    echo $(curl -s -X POST https://appsflyer.atlassian.net/rest/api/3/search/jql --user $JIRA_TOKEN -H \"Content-Type: application/json\" -d \"{\\\"jql\\\": \\\"fixVersion=$version_id\\\", \\\"fields\\\": [\\\"summary\\\"]}\" | jq -r '.issues[] | \"- \" + .fields[\"summary\"]+\"@\"') > \"$JIRA_FIXED_VERSION-releasenotes\".txt\n    sed -i -r -e \"s/@ /\\n/gi\" \"$JIRA_FIXED_VERSION-releasenotes\".txt\n    sed -i -r -e \"s/@/\\n/gi\" \"$JIRA_FIXED_VERSION-releasenotes\".txt\n    cat \"$JIRA_FIXED_VERSION-releasenotes\".txt\nfi\ndone\nif [ fixed_version_found == false ];then\necho \"$JIRA_FIXED_VERSION is not found!\"\nexit 1\nfi"
  },
  {
    "path": ".github/workflows/Scripts/extractPackage.py",
    "content": "from importlib.resources import path\nimport re\nimport hashlib\nimport os\nimport sys\nfrom unitypackage_extractor.extractor import extractPackage\n\nclass checkPackage:\n\n    def __init__(self, pathToPackage):\n        self.pathToPackage = pathToPackage\n\n    def extractPackage(self, pathToOuptut):\n        extractPackage(self.pathToPackage, outputPath=pathToOuptut)\n\n\ndef main():\n    package = checkPackage(sys.argv[1])\n    strict_package = checkPackage(sys.argv[2])\n\n    #testing integreity of files\n    print(\"###################### \\n Extracting files in unity packages \\n ######################\")\n    package.extractPackage(\"./packageUnity\")\n    strict_package.extractPackage(\"./strictPackageUnity\")\n    \n    path_of_the_strict_directory= 'strictPackageUnity/'\n    path_of_the_directory= 'packageUnity/'\n    path_of_repo = \"Assets/\"\n    \n    files_to_not_check = [\"package.json\"]\n    files_for_strict_mode_only = [\"AppsFlyeriOSWrapper.mm\", \"AppsFlyerDependencies.xml\"]\n    \n    \n    #checksum of files\n    print(\"###################### \\n testing integreity of files \\n ######################\")\n    package.extractPackage(\"./packageUnity\")\n    for subdir, dirs, files in os.walk(path_of_repo):\n        for file in files:\n            file_in_package = os.path.join(*[path_of_the_directory, subdir,file])\n            file_in_repo = os.path.join(subdir, file)\n            file_in_strict_package = os.path.join(*[path_of_the_strict_directory, subdir,file])\n            if os.path.isfile(file_in_package) and os.path.isfile(file_in_repo) and os.path.isfile(file_in_strict_package):\n                if file in files_to_not_check:\n                    continue\n                if file in files_for_strict_mode_only:\n                    if getHash(file_in_package) != getHash(file_in_repo):\n                        print(\"❌ the file \", file, \"is not the same\")\n                        sys.exit(5)\n                    print(\"file for non strict mode \", file, \"md5 check passed ✅\") \n                    if file == \"AppsFlyeriOSWrapper.mm\":\n                       if not hasCommentedMethods(file_in_strict_package):\n                           print(\"❌ the methods are not commented in  \", file_in_strict_package)\n                           sys.exit(5)\n                       print(\"file in strict mode \", file, \" has the correct methods commented out ✅\")\n                    if file == \"AppsFlyerDependencies.xml\":\n                        if not isSrictModeDependency(file_in_strict_package):\n                            print(\"❌ the dependecy is not strict in \",file_in_strict_package )\n                            sys.exit(5)\n                        print(\"file in strict mode \", file, \" has the correct depdendency ✅\")\n                        \n        \n                else:\n                    if getHash(file_in_package) != getHash(file_in_repo) or getHash(file_in_repo) != getHash(file_in_strict_package):\n                        print(\"❌ the file\" , file, \"is not the same\")\n                        sys.exit(5)\n                    print(\"file \", file, \"md5 check passed ✅\")\n\n\n        \n    \ndef getHash(filePath):\n    md5 = hashlib.md5()\n    with open(filePath,'rb') as file:\n        hash = file.read()\n        md5.update(hash)\n        return md5.hexdigest()\n    \n    \n#check that only the two methods are commented in the strict mode package\ndef hasCommentedMethods(file):\n    print(\"###################### \\n checking that the methods are commented in the strict mode package \\n ######################\")\n    textfile = open(file, 'r')\n    filetext = textfile.read()\n    textfile.close()\n    matches1 = re.findall(\"[/]+.*\\[+AppsFlyerLib.*disableAdvertisingIdentifier\", filetext)\n    matches2 = re.findall(\"[/]+.*\\[+AppsFlyerLib.*waitForATTUserAuthorizationWithTimeoutInterval\", filetext)\n    return len(matches1) == 1 and len(matches2) == 1\n\n#check that we are using the strict dependency in strict mode package\ndef isSrictModeDependency(file):\n    print(\"###################### \\nchecking the depdendency for the strict mode \\n ######################\")\n    textfile = open(file, 'r')\n    filetext = textfile.read()\n    textfile.close()\n    match = re.findall(\"AppsFlyerFramework/Strict\", filetext)\n    return len(match)>0\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": ".github/workflows/activation.yml",
    "content": "name: Acquire activation file for Unity\non:\n  push:\n    branches:\n      - dev/RD-81493/unit-tests\njobs:\n  activation:\n    name: Request manual activation file 🔑\n    runs-on: ubuntu-latest\n    steps:\n      # Request manual activation file\n      - name: Request manual activation file\n        id: getManualLicenseFile\n        uses: game-ci/unity-request-activation-file@v2\n      # Upload artifact (Unity_v20XX.X.XXXX.alf)\n      - name: Expose as artifact\n        uses: actions/upload-artifact@v2\n        with:\n          name: ${{ steps.getManualLicenseFile.outputs.filePath }}\n          path: ${{ steps.getManualLicenseFile.outputs.filePath }}\n"
  },
  {
    "path": ".github/workflows/check_packages.yml",
    "content": "name: check packages and release to upm\n\non:\n  workflow_call:\n    inputs:\n      plugin_version:\n        required: true\n        type: string\n\njobs:\n  check-packages:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: get version\n        run: | \n          echo \"PLUGIN_VERSION=${{ inputs.plugin_version }}\" >> $GITHUB_ENV\n        \n      - name: setup python\n        uses: actions/setup-python@v4\n        with:\n          python-version: '3.9'\n      - name: install python packages\n        run: |\n          python -m pip install --upgrade pip\n          pip install unitypackage_extractor\n      - name: execute py script\n        run:\n          python .github/workflows/Scripts/extractPackage.py appsflyer-unity-plugin-${{env.PLUGIN_VERSION}}.unitypackage strict-mode-sdk/appsflyer-unity-plugin-strict-mode-${{env.PLUGIN_VERSION}}.unitypackage\n          \n  release-upm:\n    runs-on: ubuntu-latest\n    needs: check-packages\n    steps:\n      - uses: actions/checkout@v4\n      - name: split branch\n        env:\n            COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n            COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          git branch -d upm &> /dev/null || echo upm branch not found\n          git subtree split -P Assets/AppsFlyer -b upm\n          git checkout upm\n          echo \"Checked out to upm branch\"\n          git config --global user.name $COMMIT_AUTHOR\n          git config --global user.email $COMMIT_EMAIL\n          git rm -r Tests\n          git commit -m \"Remove Tests folder from upm branch\"\n          echo \"Removed Tests folder\"\n          git push -f -u origin upm\n      - name: create tag\n        run: |\n          git tag v${{inputs.plugin_version}}\n          git push origin v${{inputs.plugin_version}}\n          echo \"Release v${{inputs.plugin_version}} to upm :bookmark:\"\n\n\n  strict-upm:\n    runs-on: ubuntu-latest\n    needs: check-packages\n    steps:\n      - uses: actions/checkout@v4\n      - name: split branch\n        env:\n            COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n            COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          git branch -d Strict-upm &> /dev/null || echo Strict-upm branch not found\n          git subtree split -P Assets/AppsFlyer -b Strict-upm\n          git checkout Strict-upm\n          echo \"Checked out to Strict-upm branch\"\n          git config --global user.name $COMMIT_AUTHOR\n          git config --global user.email $COMMIT_EMAIL\n          git rm -r Tests\n          git commit -m \"Remove Tests folder from Strict-upm branch\"\n          echo \"Removed Tests folder\"\n      - name: Modify for strict mode\n        run: |\n          echo \"Changing AppsFlyerFramework to Strict Mode\"\n          grep -q \"AppsFlyerFramework\" Editor/AppsFlyerDependencies.xml\n          sed -i 's/AppsFlyerFramework/AppsFlyerFramework\\/Strict/g' Editor/AppsFlyerDependencies.xml\n          echo \"Changing package.json to Strict Mode\"\n          grep -q \"AppsFlyer Unity plugin\" ./package.json\n          sed -i 's/AppsFlyer Unity plugin/AppsFlyer Unity plugin strict mode/g' ./package.json\n          echo \"Commenting out disableAdvertisingIdentifier\"\n          grep -q \"\\[AppsFlyerLib shared\\].disableAdvertisingIdentifier\" Plugins/iOS/AppsFlyeriOSWrapper.mm\n          sed -i 's/\\[AppsFlyerLib shared\\].disableAdvertisingIdentifier/\\/\\/\\[AppsFlyerLib shared\\].disableAdvertisingIdentifier/g' Plugins/iOS/AppsFlyeriOSWrapper.mm\n          echo \"Commenting out waitForATTUserAuthorizationWithTimeoutInterval\"\n          grep -q \"\\[\\[AppsFlyerLib shared\\] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval\\];\" Plugins/iOS/AppsFlyeriOSWrapper.mm\n          sed -i 's/\\[\\[AppsFlyerLib shared\\] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval\\];/\\/\\/\\[\\[AppsFlyerLib shared\\] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval\\];/g' Plugins/iOS/AppsFlyeriOSWrapper.mm\n\n      - name: Commit changes and push\n        env:\n            COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n            COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          git config user.name $COMMIT_AUTHOR\n          git config user.email $COMMIT_EMAIL\n          git add -A\n          git commit -m \"update package.json\"\n          git push -f -u origin Strict-upm\n      - name: create tag\n        run: |\n          git tag Strict-v${{inputs.plugin_version}}\n          git push origin Strict-v${{inputs.plugin_version}}\n          echo \"Release Strict mode v${{inputs.plugin_version}} to upm :bookmark:\"\n      \n     \n"
  },
  {
    "path": ".github/workflows/close_inactive_issues.yml",
    "content": "# This workflow triggers the org-wide reusable workflow to close inactive issues on a schedule\non:\n  schedule:\n    - cron: \"0 10 * * *\" # Runs daily at 10:00 UTC\n  workflow_dispatch:\n\njobs:\n  close-issues:\n    uses: AppsFlyerSDK/github-common-workflow-and-template/.github/workflows/close_inactive_issues.yml@main\n    secrets: inherit "
  },
  {
    "path": ".github/workflows/issues_workflow.yml",
    "content": "name: Close inactive issues\non:\n  schedule:\n    - cron: \"30 9 * * 0\"\n\njobs:\n  close-issues:\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n    steps:\n      - uses: actions/stale@v5\n        with:\n          days-before-issue-stale: 30\n          days-before-issue-close: 14\n          stale-issue-label: \"stale\"\n          stale-issue-message: \"This issue is stale because it has been open for 30 days with no activity.\"\n          close-issue-message: \"This issue was closed because it has been inactive for 14 days since being marked as stale.\"\n          days-before-pr-stale: -1\n          days-before-pr-close: -1\n          repo-token: ${{ secrets.GITHUB_TOKEN }}"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: Test runner unity-appsflyer-plugin\n\non:\n  workflow_call:\n\njobs:\n  run-unity-tests:\n    name: Run ${{ matrix.testMode }} tests for ${{ matrix.targetPlatform }}\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        testMode: [playmode]\n        targetPlatform: [iOS, Android, Shared]\n\n    steps:\n      - uses: actions/checkout@v2\n        with:\n          lfs: true\n\n      - name: Free up disk space\n        run: |\n          rm -rf /usr/share/dotnet/\n          rm -rf \"/usr/local/share/boost\"\n          rm -rf \"$AGENT_TOOLSDIRECTORY\"\n          rm -rf /opt/ghc\n\n      - uses: actions/cache@v4\n        with:\n          path: Library\n          key: Library-${{ matrix.targetPlatform }}-${{ matrix.testMode }}-${{ hashFiles('**/*.cs') }}\n          restore-keys: |\n            Library-${{ matrix.targetPlatform }}-${{ matrix.testMode }}-\n            Library-${{ matrix.targetPlatform }}-\n            Library-\n\n      - uses: game-ci/unity-test-runner@v4\n        id: tests\n        env:\n          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}\n          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}\n          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}\n        with:\n          projectPath: .\n          testMode: ${{ matrix.testMode }}\n          artifactsPath: ${{ matrix.targetPlatform }}-artifacts\n          githubToken: ${{ secrets.GITHUB_TOKEN }}\n          checkName: ${{ matrix.targetPlatform }} Test Results\n          customParameters: >\n            -nographics\n            -buildTarget ${{ matrix.targetPlatform == 'Shared' && 'StandaloneLinux64' || matrix.targetPlatform }}\n            -defineSymbols ${{ matrix.targetPlatform == 'Shared' && '' || format('UNITY_{0}', matrix.targetPlatform) }}\n\n      - name: Upload test results\n        if: always()\n        uses: actions/upload-artifact@v4\n        with:\n          name: Test results - ${{ matrix.targetPlatform }}\n          path: ${{ steps.tests.outputs.artifactsPath }}\n"
  },
  {
    "path": ".github/workflows/readme_sync.yml",
    "content": "name: Sync `docs` directory to ReadMe\n\n# Run workflow for every push to the `main` branch\non:\n  push:\n    branches:\n      - master\n\njobs:\n  sync:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout this repo\n        uses: actions/checkout@v3\n\n      # Run GitHub Action to sync docs in `documentation` directory\n      - name: GitHub Action\n        # We recommend specifying a fixed version, i.e. @7.5.0\n        # Docs: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#example-using-versioned-actions\n        uses: readmeio/rdme@7.5.0\n        with:\n          rdme: docs ./docs --key=${{ secrets.README_SYNC_API_KEY }} --version=0.1"
  },
  {
    "path": ".github/workflows/release_QA_workflow.yml",
    "content": "name: plugin release to QA\n\non:\n  push:\n    branches:\n      - releases/[0-9]+.x.x/[0-9]+.[0-9]+.x/[0-9]+.[0-9]+.[0-9]+-rc[0-9]+\n    paths-ignore:\n      - master\n\njobs:\n  Run-Unit-Tests:\n    uses: ./.github/workflows/main.yml\n    secrets: inherit\n\n  Release-To-QA:\n    needs: [Run-Unit-Tests]\n    uses: ./.github/workflows/release_to_QA.yml\n    secrets: inherit"
  },
  {
    "path": ".github/workflows/release_production_workflow.yml",
    "content": "name: plugin release to Production workflow\n\non:\n  pull_request:\n    types:\n      - closed\n    branches:\n      - 'master'\n    paths-ignore:\n      - '**.md'\n      - 'docs/**.md'\n      - '**.sh'\n\njobs:\n  Prepare-Release:\n    if: github.event.pull_request.merged == true\n    runs-on: ubuntu-latest\n    outputs:\n      output1: ${{ steps.tag-step.outputs.PLUGIN_VERSION}}\n      output2: ${{ steps.tag-step.outputs.RELEASE_BRANCH_NAME}}\n    steps:\n      - uses: actions/checkout@v3\n      - name: Login to GitHub\n        env:\n          COMMIT_AUTHOR: ${{ secrets.CI_USERNAME}}\n          COMMIT_EMAIL: ${{ secrets.CI_EMAIL}}\n        run: |\n          git config --global user.name $COMMIT_AUTHOR\n          git config --global user.email $COMMIT_EMAIL\n\n      - uses: mdecoleman/pr-branch-name@1.2.0\n        id: vars\n        with:\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n      - name: Determine release tag and release branch\n        id: tag-step\n        run: |\n          TAG=$(echo \"${{ steps.vars.outputs.branch }}\" | grep -Eo '[0-9]+.[0-9]+.[0-9]+')\n          echo \"PLUGIN_VERSION=$TAG\" >> $GITHUB_ENV\n          echo \"PLUGIN_VERSION=$TAG\" >> $GITHUB_OUTPUT\n          echo \"RELEASE_BRANCH_NAME=${{ steps.vars.outputs.branch }}\" >> $GITHUB_ENV\n          echo \"RELEASE_BRANCH_NAME=${{ steps.vars.outputs.branch }}\" >> $GITHUB_OUTPUT\n\n  Check-Packages:\n    needs: [Prepare-Release]\n    uses: ./.github/workflows/check_packages.yml\n    with:\n      plugin_version: ${{ needs.Prepare-Release.outputs.output1 }}\n    secrets: inherit\n\n  Update-Links:\n    needs: [Prepare-Release, Check-Packages]\n    uses: ./.github/workflows/update_links.yml\n    secrets: inherit\n\n  Generate-Tag:\n    needs: [Prepare-Release, Check-Packages, Update-Links]\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Create a version tag and push it\n        run: |\n          echo \"Pushing release tag: ${{ needs.Prepare-Release.outputs.output1 }}!\"\n          git checkout master\n          echo \"Checked out to master\"\n          git pull origin master\n          git tag ${{ needs.Prepare-Release.outputs.output1 }}\n          echo \"Created release tag\"\n          git push origin ${{needs.Prepare-Release.outputs.output1}}\n          echo \"Pushed release tag ${{ needs.Prepare-Release.outputs.output1 }}\"\n\n  Release-To-Production:\n    needs: [Prepare-Release, Check-Packages, Update-Links, Generate-Tag]\n    uses: ./.github/workflows/release_to_production.yml\n    with:\n      plugin_version: ${{ needs.Prepare-Release.outputs.output1 }}\n      branch_name: ${{ needs.Prepare-Release.outputs.output2 }}\n    secrets: inherit"
  },
  {
    "path": ".github/workflows/release_to_QA.yml",
    "content": "name: Release to QA\n\non:\n  workflow_call:\n\njobs:\n  Release-To-QA:\n    runs-on: ubuntu-latest\n    environment: Staging\n    steps:\n      - uses: actions/checkout@v3\n      - name: Login to Github\n        env:\n          COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n          COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          git config --global user.name $COMMIT_AUTHOR\n          git config --global user.email $COMMIT_EMAIL\n\n      - name: Check fixed version and compare issues on Jira\n        env:\n          JIRA_TOKEN: ${{ secrets.CI_JIRA_TOKEN }}\n          BRANCH_NAME: ${{ github.ref_name }}\n        run: |\n          plugin_version=$(echo \"$BRANCH_NAME\" | grep -Eo '[0-9]+.[0-9]+.[0-9]+')\n          jira_fixed_version=\"Unity SDK v$plugin_version\"\n          echo \"JIRA_FIXED_VERSION=$jira_fixed_version\" >> $GITHUB_ENV\n          chmod +x .github/workflows/Scripts/checkJira.sh\n          .github/workflows/Scripts/checkJira.sh $JIRA_TOKEN \"$jira_fixed_version\"\n\n      - name: Update package.json\n        env:\n          BRANCH_NAME: ${{ github.ref_name }}\n          COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n          COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          echo \"updating package.json version\"\n          plugin_version=$(echo \"$BRANCH_NAME\" | grep -Eo '[0-9]+.[0-9]+.[0-9]+')\n          sed -E -i \"s/\\\"version\\\": \\\"[0-9]+.[0-9]+.[0-9]+\\\"/\\\"version\\\": \\\"$plugin_version\\\"/g\" Assets/AppsFlyer/package.json\n\n          if [[ -n $(git status -s) ]]; then\n            echo \"Commit and push\"\n            git add Assets/AppsFlyer/package.json\n            git commit -m \"update package.json\"\n            git push origin $BRANCH_NAME\n          else\n            echo \"package.json version is already up to date\"\n          fi\n\n      - name: Send slack report\n        env:\n          SLACK_TOKEN: ${{ secrets.CI_SLACK_TOKEN }}\n        run: |\n          ios_af_sdk_version=$(cat README.md | grep -Eo 'iOS AppsFlyer SDK v[0-9]+.[0-9]+.[0-9]+')\n          android_af_sdk_version=$(cat README.md | grep -Eo 'Android AppsFlyer SDK v[0-9]+.[0-9]+.[0-9]+')\n          \n          # Extract plugin version from branch name\n          plugin_version=$(echo \"${{github.ref_name}}\" | grep -Eo '[0-9]+.[0-9]+.[0-9]+')\n          \n          # Send webhook to Slack with all required parameters\n          curl -X POST -H 'Content-type: application/json' --data '{\n            \"plugin_version\": \"'\"$plugin_version\"'\",\n            \"git_branch\": \"'\"${{github.ref_name}}\"'\",\n            \"ios_sdk_dependency\": \"'\"$ios_af_sdk_version\"'\",\n            \"android_sdk_dependency\": \"'\"$android_af_sdk_version\"'\",\n            \"version_changes\": \"New Unity Plugin Release: Unity SDK v'\"$plugin_version\"'\",\n            \"deploy_type\": \"QA\"\n          }' \"$SLACK_TOKEN\"\n\n"
  },
  {
    "path": ".github/workflows/release_to_production.yml",
    "content": "name: plugin release to Production\n\non:\n  workflow_call:\n    inputs:\n      plugin_version:\n        required: true\n        type: string\n      branch_name:\n        required: true\n        type: string\n\njobs:\n  Release-To-Production:\n    runs-on: ubuntu-latest\n    environment: Production\n    steps:\n      - uses: actions/checkout@v3\n      - name: Login to Github\n        env:\n          COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n          COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n        run: |\n          git config --global user.name $COMMIT_AUTHOR\n          git config --global user.email $COMMIT_EMAIL\n\n      - name: Create GitHub Release\n        env:\n          VTAG: v${{ inputs.plugin_version }}\n          TAG: ${{ inputs.plugin_version }}\n        uses: \"actions/github-script@v5\"\n        with:\n          github-token: \"${{ secrets.GITHUB_TOKEN }}\"\n          script: |\n            try {\n              await github.rest.repos.createRelease({\n                draft: false,\n                generate_release_notes: false,\n                name: process.env.VTAG,\n                owner: context.repo.owner,\n                prerelease: false,\n                repo: context.repo.repo,\n                tag_name: process.env.TAG\n              });\n            } catch (error) {\n              core.setFailed(error.message);\n            }\n      - name: Send slack report\n        env:\n          SLACK_TOKEN: ${{ secrets.CI_SLACK_TOKEN }}\n          JIRA_TOKEN: ${{ secrets.CI_JIRA_TOKEN }}\n        run: |\n          jira_fixed_version=\"Unity SDK v${{inputs.plugin_version}}\"\n          chmod +x .github/workflows/Scripts/checkJira.sh\n          .github/workflows/Scripts/checkJira.sh $JIRA_TOKEN \"$jira_fixed_version\"\n          \n          ios_af_sdk_version=$(cat README.md | grep -Eo 'iOS AppsFlyer SDK v[0-9]+.[0-9]+.[0-9]+')\n          android_af_sdk_version=$(cat README.md | grep -Eo 'Android AppsFlyer SDK v[0-9]+.[0-9]+.[0-9]+')\n          \n          # Create a simple release message without the text file\n          release_message=\"🚀 PRODUCTION RELEASE: Unity Plugin ${{inputs.plugin_version}}\"\n          \n          # Send webhook to Slack with all required parameters\n          curl -X POST -H 'Content-type: application/json' --data '{\n            \"plugin_version\": \"'\"${{inputs.plugin_version}}\"'\",\n            \"git_branch\": \"'\"${{inputs.branch_name}}\"'\",\n            \"ios_sdk_dependency\": \"'\"$ios_af_sdk_version\"'\",\n            \"android_sdk_dependency\": \"'\"$android_af_sdk_version\"'\",\n            \"version_changes\": \"🚀 PRODUCTION RELEASE: Unity Plugin ${{inputs.plugin_version}}\",\n            \"deploy_type\": \"PRODUCTION\"\n          }' \"$SLACK_TOKEN\"\n"
  },
  {
    "path": ".github/workflows/responseToSupportIssue.yml",
    "content": "# This workflow triggers the org-wide reusable workflow to respond to issues labeled as 'support'\non:\n  issues:\n    types:\n      - labeled\n  workflow_dispatch:\n\njobs:\n  add-comment:\n    uses: AppsFlyerSDK/github-common-workflow-and-template/.github/workflows/responseToSupportIssue.yml@main\n    secrets: inherit "
  },
  {
    "path": ".github/workflows/responseToSupportIssueOnOpen.yml",
    "content": "# This workflow triggers the org-wide reusable workflow to respond to newly opened issues\non:\n  issues:\n    types:\n      - opened\n  workflow_dispatch:\n\njobs:\n  add-comment:\n    uses: AppsFlyerSDK/github-common-workflow-and-template/.github/workflows/responseToSupportIssueOnOpen.yml@main\n    secrets: inherit "
  },
  {
    "path": ".github/workflows/test-unity-auth.yml",
    "content": "name: Test Unity Authentication\n\non:\n  workflow_dispatch:\n\njobs:\n  test-auth:\n    name: Test Unity License Activation\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Test Unity activation\n        uses: game-ci/unity-activate@v2\n        env:\n          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}\n          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}\n          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}\n\n      - name: Success message\n        run: echo \"Unity authentication successful!\" "
  },
  {
    "path": ".github/workflows/update_links.yml",
    "content": "name: update sdk links\n\non:\n    workflow_call:\n\njobs:\n  update-links:\n    runs-on: ubuntu-latest\n    steps:\n        - name: Check out repo\n          uses: actions/checkout@v4\n        - name: Update links\n          id: update-links\n          env:\n              COMMIT_AUTHOR: ${{ secrets.CI_USERNAME }}\n              COMMIT_EMAIL: ${{ secrets.CI_EMAIL }}\n          run: |\n            echo \"Getting the versions\"\n            grep -o 'spec=\"com.appsflyer:[^\"]\\+\"' Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml | sed -E 's/spec=\"com.appsflyer:([^\"]+)\"/\\1/' | awk -F':' '{print $2}' > output.txt\n            grep -o 'name=\"AppsFlyerFramework\" version=\"[^\"]\\+\"' Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml | sed -E 's/name=\"AppsFlyerFramework\" version=\"([^\"]+)\"/\\1/' >> output.txt\n\n            echo \"Changing links\"\n            android_version=$(sed -n '1p' output.txt)\n            sed -E -i \"s/af-android-sdk\\/[0-9]+.[0-9]+.[0-9]+/af-android-sdk\\/$android_version/g\" docs/Installation.md\n            sed -E -i \"s/af-android-sdk-[0-9]+.[0-9]+.[0-9]+/af-android-sdk-$android_version/g\" docs/Installation.md\n\n            wrapper_version=$(sed -n '2p' output.txt)\n            sed -E -i \"s/unity-wrapper\\/[0-9]+.[0-9]+.[0-9]+/unity-wrapper\\/$wrapper_version/g\" docs/Installation.md\n            sed -E -i \"s/unity-wrapper-[0-9]+.[0-9]+.[0-9]+/unity-wrapper-$wrapper_version/g\" docs/Installation.md\n\n            ios_version=$(sed -n '3p' output.txt)\n            major_version=\"${ios_version%%.*}\"\n            minor_version=\"${ios_version%.*}\"\n            sed -E -i \"s/appsflyer.com\\/ios\\/[0-9]+.x.x\\/[0-9]+.[0-9]+.x\\/[0-9]+.[0-9]+.[0-9]+\\/AF-iOS-SDK-v[0-9]+.[0-9]+.[0-9]+/appsflyer.com\\/ios\\/$major_version.x.x\\/$minor_version.x\\/$ios_version\\/AF-iOS-SDK-v$ios_version/g\" docs/Installation.md\n            sed -E -i \"s/unity-wrapper-[0-9]+.[0-9]+.[0-9]+/unity-wrapper-$wrapper_version/g\" docs/Installation.md\n\n            rm output.txt\n\n            if [[ -n $(git status -s) ]]; then\n                echo \"Links need updating, will create PR\"\n                git config --global user.name $COMMIT_AUTHOR\n                git config --global user.email $COMMIT_EMAIL\n                git add docs/Installation.md\n                git commit -m \"generate links\"\n                echo \"changes_made=true\" >> $GITHUB_OUTPUT\n            else\n                echo \"Links are already up to date\"\n                echo \"changes_made=false\" >> $GITHUB_OUTPUT\n            fi\n        - name: Create Pull Request\n          if: steps.update-links.outputs.changes_made == 'true'\n          uses: peter-evans/create-pull-request@v5\n          with:\n            token: ${{ secrets.GITHUB_TOKEN }}\n            commit-message: \"generate links\"\n            title: \"Update SDK links for version ${{ inputs.plugin_version || 'latest' }}\"\n            body: |\n              This PR automatically updates the SDK links in the Installation.md file.\n              \n              **Changes:**\n              - Updated Android SDK links\n              - Updated iOS SDK links  \n              - Updated Unity wrapper links\n              \n              This PR was created automatically by the release workflow.\n            branch: update-links-${{ github.run_number }}\n            base: master\n            delete-branch: true"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n*.log\nLogs/\nPackages/\nTemp/\nLibrary/\n/*/outputs/\n\n\n#android studio\nbuild\ngen\n.gradle\n.idea\n.hgcheck\ninfer-out\ncaptures\nlocal.properties\n*.orig\n*.rej\nout\nbin\ndist\n*.iml\nbuild.gradle_mine\n.DS_Store\n*.idea\n\n.vs/appsflyer-unity-plugin/xs/project-cache/\n\n.vs/appsflyer-unity-plugin/xs/\n\n.vsconfig\n\n*.sln\n\n*.csproj\n\n*.cache\n"
  },
  {
    "path": "Assets/AppsFlyer/AFAdRevenueData.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    public enum MediationNetwork : ulong\n    {      \n        GoogleAdMob = 1,\n        IronSource = 2,\n        ApplovinMax = 3,\n        Fyber = 4,\n        Appodeal = 5,\n        Admost = 6,\n        Topon = 7,\n        Tradplus = 8,\n        Yandex = 9,\n        ChartBoost = 10,\n        Unity = 11,\n        ToponPte = 12,\n        Custom = 13,\n        DirectMonetization = 14\n    }\n\n    public static class AdRevenueScheme\n    {\n        /**\n        * code ISO 3166-1 format\n        */\n        public const string COUNTRY = \"country\";\n\n        /**\n        * ID of the ad unit for the impression\n        */\n        public const string AD_UNIT = \"ad_unit\";\n\n        /**\n        * Format of the ad\n        */\n        public const string AD_TYPE = \"ad_type\";\n\n        /**\n        * ID of the ad placement for the impression\n        */\n        public const string PLACEMENT = \"placement\";\n    }\n\n    /// <summary>\n    // Data class representing ad revenue information.\n    //\n    // @property monetizationNetwork The name of the network that monetized the ad.\n    // @property mediationNetwork An instance of MediationNetwork representing the mediation service used.\n    // @property currencyIso4217Code The ISO 4217 currency code describing the currency of the revenue.\n    // @property eventRevenue The amount of revenue generated by the ad.\n    /// </summary>\n    public class AFAdRevenueData\n    {\n        public string monetizationNetwork { get; private set; }\n        public MediationNetwork mediationNetwork { get; private set; }\n        public string currencyIso4217Code { get; private set; }\n        public double eventRevenue { get; private set; }\n\n        public AFAdRevenueData(string monetization, MediationNetwork mediation, string currency, double revenue)\n        {\n            monetizationNetwork = monetization;\n            mediationNetwork = mediation;\n            currencyIso4217Code = currency;\n            eventRevenue = revenue;\n        }\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AFAdRevenueData.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 49e1906ae949e4bfea400bd1da9f7e39\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AFInAppEvents.cs",
    "content": "﻿using UnityEngine;\nusing System.Collections;\n\npublic class AFInAppEvents {\n\t/**\n\t * Event Type\n\t * */\n\tpublic const string LEVEL_ACHIEVED = \"af_level_achieved\";\n\tpublic const string ADD_PAYMENT_INFO = \"af_add_payment_info\";\n\tpublic const string ADD_TO_CART = \"af_add_to_cart\";\n\tpublic const string ADD_TO_WISH_LIST = \"af_add_to_wishlist\";\n\tpublic const string COMPLETE_REGISTRATION = \"af_complete_registration\";\n\tpublic const string TUTORIAL_COMPLETION = \"af_tutorial_completion\";\n\tpublic const string INITIATED_CHECKOUT = \"af_initiated_checkout\";\n\tpublic const string PURCHASE = \"af_purchase\";\n\tpublic const string RATE = \"af_rate\";\n\tpublic const string SEARCH = \"af_search\";\n\tpublic const string SPENT_CREDIT = \"af_spent_credits\";\n\tpublic const string ACHIEVEMENT_UNLOCKED = \"af_achievement_unlocked\";\n\tpublic const string CONTENT_VIEW = \"af_content_view\";\n\tpublic const string TRAVEL_BOOKING = \"af_travel_booking\";\n\tpublic const string SHARE = \"af_share\";\n\tpublic const string INVITE = \"af_invite\";\n\tpublic const string LOGIN = \"af_login\";\n\tpublic const string RE_ENGAGE = \"af_re_engage\";\n\tpublic const string UPDATE = \"af_update\";\n\tpublic const string OPENED_FROM_PUSH_NOTIFICATION = \"af_opened_from_push_notification\";\n\tpublic const string LOCATION_CHANGED = \"af_location_changed\";\n\tpublic const string LOCATION_COORDINATES = \"af_location_coordinates\";\n\tpublic const string ORDER_ID = \"af_order_id\";\n\t/**\n\t * Event Parameter Name\n\t * **/\n\tpublic const string LEVEL = \"af_level\";\n\tpublic const string SCORE = \"af_score\";\n\tpublic const string SUCCESS = \"af_success\";\n\tpublic const string PRICE = \"af_price\";\n\tpublic const string CONTENT_TYPE = \"af_content_type\";\n\tpublic const string CONTENT_ID = \"af_content_id\";\n\tpublic const string CONTENT_LIST = \"af_content_list\";\n\tpublic const string CURRENCY = \"af_currency\";\n\tpublic const string QUANTITY = \"af_quantity\";\n\tpublic const string REGSITRATION_METHOD = \"af_registration_method\";\n\tpublic const string PAYMENT_INFO_AVAILIBLE = \"af_payment_info_available\";\n\tpublic const string MAX_RATING_VALUE = \"af_max_rating_value\";\n\tpublic const string RATING_VALUE = \"af_rating_value\";\n\tpublic const string SEARCH_STRING = \"af_search_string\";\n\tpublic const string DATE_A = \"af_date_a\";\n\tpublic const string DATE_B = \"af_date_b\";\n\tpublic const string DESTINATION_A = \"af_destination_a\";\n\tpublic const string DESTINATION_B = \"af_destination_b\";\n\tpublic const string DESCRIPTION = \"af_description\";\n\tpublic const string CLASS = \"af_class\";\n\tpublic const string EVENT_START = \"af_event_start\";\n\tpublic const string EVENT_END = \"af_event_end\";\n\tpublic const string LATITUDE = \"af_lat\";\n\tpublic const string LONGTITUDE = \"af_long\";\n\tpublic const string CUSTOMER_USER_ID = \"af_customer_user_id\";\n\tpublic const string VALIDATED = \"af_validated\";\n\tpublic const string REVENUE = \"af_revenue\";\n\tpublic const string RECEIPT_ID = \"af_receipt_id\";\n\tpublic const string PARAM_1 = \"af_param_1\";\n\tpublic const string PARAM_2 = \"af_param_2\";\n\tpublic const string PARAM_3 = \"af_param_3\";\n\tpublic const string PARAM_4 = \"af_param_4\";\n\tpublic const string PARAM_5 = \"af_param_5\";\n\tpublic const string PARAM_6 = \"af_param_6\";\n\tpublic const string PARAM_7 = \"af_param_7\";\n\tpublic const string PARAM_8 = \"af_param_8\";\n\tpublic const string PARAM_9 = \"af_param_9\";\n\tpublic const string PARAM_10 = \"af_param_10\";\n}"
  },
  {
    "path": "Assets/AppsFlyer/AFInAppEvents.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 4075c6cf6f3d94b9a9f37f826e6a0e6f\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AFMiniJSON.cs",
    "content": "/*\n * Copyright (c) 2013 Calvin Rien\n *\n * Based on the JSON parser by Patrick van Bergen\n * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html\n *\n * Simplified it so that it doesn't throw exceptions\n * and can be used in Unity iPhone with maximum code stripping.\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace AFMiniJSON {\n    // Example usage:\n    //\n    //  using UnityEngine;\n    //  using System.Collections;\n    //  using System.Collections.Generic;\n    //  using MiniJSON;\n    //\n    //  public class MiniJSONTest : MonoBehaviour {\n    //      void Start () {\n    //          var jsonString = \"{ \\\"array\\\": [1.44,2,3], \" +\n    //                          \"\\\"object\\\": {\\\"key1\\\":\\\"value1\\\", \\\"key2\\\":256}, \" +\n    //                          \"\\\"string\\\": \\\"The quick brown fox \\\\\\\"jumps\\\\\\\" over the lazy dog \\\", \" +\n    //                          \"\\\"unicode\\\": \\\"\\\\u3041 Men\\u00fa sesi\\u00f3n\\\", \" +\n    //                          \"\\\"int\\\": 65536, \" +\n    //                          \"\\\"float\\\": 3.1415926, \" +\n    //                          \"\\\"bool\\\": true, \" +\n    //                          \"\\\"null\\\": null }\";\n    //\n    //          var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;\n    //\n    //          Debug.Log(\"deserialized: \" + dict.GetType());\n    //          Debug.Log(\"dict['array'][0]: \" + ((List<object>) dict[\"array\"])[0]);\n    //          Debug.Log(\"dict['string']: \" + (string) dict[\"string\"]);\n    //          Debug.Log(\"dict['float']: \" + (double) dict[\"float\"]); // floats come out as doubles\n    //          Debug.Log(\"dict['int']: \" + (long) dict[\"int\"]); // ints come out as longs\n    //          Debug.Log(\"dict['unicode']: \" + (string) dict[\"unicode\"]);\n    //\n    //          var str = Json.Serialize(dict);\n    //\n    //          Debug.Log(\"serialized: \" + str);\n    //      }\n    //  }\n\n    /// <summary>\n    /// This class encodes and decodes JSON strings.\n    /// Spec. details, see http://www.json.org/\n    ///\n    /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.\n    /// All numbers are parsed to doubles.\n    /// </summary>\n    public static class Json {\n        /// <summary>\n        /// Parses the string json into a value\n        /// </summary>\n        /// <param name=\"json\">A JSON string.</param>\n        /// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>\n        public static object Deserialize(string json) {\n            // save the string for debug information\n            if (json == null) {\n                return null;\n            }\n\n            return Parser.Parse(json);\n        }\n\n        sealed class Parser : IDisposable {\n            const string WORD_BREAK = \"{}[],:\\\"\";\n\n            public static bool IsWordBreak(char c) {\n                return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;\n            }\n\n            enum TOKEN {\n                NONE,\n                CURLY_OPEN,\n                CURLY_CLOSE,\n                SQUARED_OPEN,\n                SQUARED_CLOSE,\n                COLON,\n                COMMA,\n                STRING,\n                NUMBER,\n                TRUE,\n                FALSE,\n                NULL\n            };\n\n            StringReader json;\n\n            Parser(string jsonString) {\n                json = new StringReader(jsonString);\n            }\n\n            public static object Parse(string jsonString) {\n                using (var instance = new Parser(jsonString)) {\n                    return instance.ParseValue();\n                }\n            }\n\n            public void Dispose() {\n                json.Dispose();\n                json = null;\n            }\n\n            Dictionary<string, object> ParseObject() {\n                Dictionary<string, object> table = new Dictionary<string, object>();\n\n                // ditch opening brace\n                json.Read();\n\n                // {\n                while (true) {\n                    switch (NextToken) {\n                    case TOKEN.NONE:\n                        return null;\n                    case TOKEN.COMMA:\n                        continue;\n                    case TOKEN.CURLY_CLOSE:\n                        return table;\n                    default:\n                        // name\n                        string name = ParseString();\n                        if (name == null) {\n                            return null;\n                        }\n\n                        // :\n                        if (NextToken != TOKEN.COLON) {\n                            return null;\n                        }\n                        // ditch the colon\n                        json.Read();\n\n                        // value\n                        table[name] = ParseValue();\n                        break;\n                    }\n                }\n            }\n\n            List<object> ParseArray() {\n                List<object> array = new List<object>();\n\n                // ditch opening bracket\n                json.Read();\n\n                // [\n                var parsing = true;\n                while (parsing) {\n                    TOKEN nextToken = NextToken;\n\n                    switch (nextToken) {\n                    case TOKEN.NONE:\n                        return null;\n                    case TOKEN.COMMA:\n                        continue;\n                    case TOKEN.SQUARED_CLOSE:\n                        parsing = false;\n                        break;\n                    default:\n                        object value = ParseByToken(nextToken);\n\n                        array.Add(value);\n                        break;\n                    }\n                }\n\n                return array;\n            }\n\n            object ParseValue() {\n                TOKEN nextToken = NextToken;\n                return ParseByToken(nextToken);\n            }\n\n            object ParseByToken(TOKEN token) {\n                switch (token) {\n                case TOKEN.STRING:\n                    return ParseString();\n                case TOKEN.NUMBER:\n                    return ParseNumber();\n                case TOKEN.CURLY_OPEN:\n                    return ParseObject();\n                case TOKEN.SQUARED_OPEN:\n                    return ParseArray();\n                case TOKEN.TRUE:\n                    return true;\n                case TOKEN.FALSE:\n                    return false;\n                case TOKEN.NULL:\n                    return null;\n                default:\n                    return null;\n                }\n            }\n\n            string ParseString() {\n                StringBuilder s = new StringBuilder();\n                char c;\n\n                // ditch opening quote\n                json.Read();\n\n                bool parsing = true;\n                while (parsing) {\n\n                    if (json.Peek() == -1) {\n                        parsing = false;\n                        break;\n                    }\n\n                    c = NextChar;\n                    switch (c) {\n                    case '\"':\n                        parsing = false;\n                        break;\n                    case '\\\\':\n                        if (json.Peek() == -1) {\n                            parsing = false;\n                            break;\n                        }\n\n                        c = NextChar;\n                        switch (c) {\n                        case '\"':\n                        case '\\\\':\n                        case '/':\n                            s.Append(c);\n                            break;\n                        case 'b':\n                            s.Append('\\b');\n                            break;\n                        case 'f':\n                            s.Append('\\f');\n                            break;\n                        case 'n':\n                            s.Append('\\n');\n                            break;\n                        case 'r':\n                            s.Append('\\r');\n                            break;\n                        case 't':\n                            s.Append('\\t');\n                            break;\n                        case 'u':\n                            var hex = new char[4];\n\n                            for (int i=0; i< 4; i++) {\n                                hex[i] = NextChar;\n                            }\n\n                            s.Append((char) Convert.ToInt32(new string(hex), 16));\n                            break;\n                        }\n                        break;\n                    default:\n                        s.Append(c);\n                        break;\n                    }\n                }\n\n                return s.ToString();\n            }\n\n            object ParseNumber() {\n                string number = NextWord;\n\n                if (number.IndexOf('.') == -1) {\n                    long parsedInt;\n                    Int64.TryParse(number, out parsedInt);\n                    return parsedInt;\n                }\n\n                double parsedDouble;\n                Double.TryParse(number, out parsedDouble);\n                return parsedDouble;\n            }\n\n            void EatWhitespace() {\n                while (Char.IsWhiteSpace(PeekChar)) {\n                    json.Read();\n\n                    if (json.Peek() == -1) {\n                        break;\n                    }\n                }\n            }\n\n            char PeekChar {\n                get {\n                    return Convert.ToChar(json.Peek());\n                }\n            }\n\n            char NextChar {\n                get {\n                    return Convert.ToChar(json.Read());\n                }\n            }\n\n            string NextWord {\n                get {\n                    StringBuilder word = new StringBuilder();\n\n                    while (!IsWordBreak(PeekChar)) {\n                        word.Append(NextChar);\n\n                        if (json.Peek() == -1) {\n                            break;\n                        }\n                    }\n\n                    return word.ToString();\n                }\n            }\n\n            TOKEN NextToken {\n                get {\n                    EatWhitespace();\n\n                    if (json.Peek() == -1) {\n                        return TOKEN.NONE;\n                    }\n\n                    switch (PeekChar) {\n                    case '{':\n                        return TOKEN.CURLY_OPEN;\n                    case '}':\n                        json.Read();\n                        return TOKEN.CURLY_CLOSE;\n                    case '[':\n                        return TOKEN.SQUARED_OPEN;\n                    case ']':\n                        json.Read();\n                        return TOKEN.SQUARED_CLOSE;\n                    case ',':\n                        json.Read();\n                        return TOKEN.COMMA;\n                    case '\"':\n                        return TOKEN.STRING;\n                    case ':':\n                        return TOKEN.COLON;\n                    case '0':\n                    case '1':\n                    case '2':\n                    case '3':\n                    case '4':\n                    case '5':\n                    case '6':\n                    case '7':\n                    case '8':\n                    case '9':\n                    case '-':\n                        return TOKEN.NUMBER;\n                    }\n\n                    switch (NextWord) {\n                    case \"false\":\n                        return TOKEN.FALSE;\n                    case \"true\":\n                        return TOKEN.TRUE;\n                    case \"null\":\n                        return TOKEN.NULL;\n                    }\n\n                    return TOKEN.NONE;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string\n        /// </summary>\n        /// <param name=\"json\">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>\n        /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>\n        public static string Serialize(object obj) {\n            return Serializer.Serialize(obj);\n        }\n\n        sealed class Serializer {\n            StringBuilder builder;\n\n            Serializer() {\n                builder = new StringBuilder();\n            }\n\n            public static string Serialize(object obj) {\n                var instance = new Serializer();\n\n                instance.SerializeValue(obj);\n\n                return instance.builder.ToString();\n            }\n\n            void SerializeValue(object value) {\n                IList asList;\n                IDictionary asDict;\n                string asStr;\n\n                if (value == null) {\n                    builder.Append(\"null\");\n                } else if ((asStr = value as string) != null) {\n                    SerializeString(asStr);\n                } else if (value is bool) {\n                    builder.Append((bool) value ? \"true\" : \"false\");\n                } else if ((asList = value as IList) != null) {\n                    SerializeArray(asList);\n                } else if ((asDict = value as IDictionary) != null) {\n                    SerializeObject(asDict);\n                } else if (value is char) {\n                    SerializeString(new string((char) value, 1));\n                } else {\n                    SerializeOther(value);\n                }\n            }\n\n            void SerializeObject(IDictionary obj) {\n                bool first = true;\n\n                builder.Append('{');\n\n                foreach (object e in obj.Keys) {\n                    if (!first) {\n                        builder.Append(',');\n                    }\n\n                    SerializeString(e.ToString());\n                    builder.Append(':');\n\n                    SerializeValue(obj[e]);\n\n                    first = false;\n                }\n\n                builder.Append('}');\n            }\n\n            void SerializeArray(IList anArray) {\n                builder.Append('[');\n\n                bool first = true;\n\n                foreach (object obj in anArray) {\n                    if (!first) {\n                        builder.Append(',');\n                    }\n\n                    SerializeValue(obj);\n\n                    first = false;\n                }\n\n                builder.Append(']');\n            }\n\n            void SerializeString(string str) {\n                builder.Append('\\\"');\n\n                char[] charArray = str.ToCharArray();\n                foreach (var c in charArray) {\n                    switch (c) {\n                    case '\"':\n                        builder.Append(\"\\\\\\\"\");\n                        break;\n                    case '\\\\':\n                        builder.Append(\"\\\\\\\\\");\n                        break;\n                    case '\\b':\n                        builder.Append(\"\\\\b\");\n                        break;\n                    case '\\f':\n                        builder.Append(\"\\\\f\");\n                        break;\n                    case '\\n':\n                        builder.Append(\"\\\\n\");\n                        break;\n                    case '\\r':\n                        builder.Append(\"\\\\r\");\n                        break;\n                    case '\\t':\n                        builder.Append(\"\\\\t\");\n                        break;\n                    default:\n                        int codepoint = Convert.ToInt32(c);\n                        if ((codepoint >= 32) && (codepoint <= 126)) {\n                            builder.Append(c);\n                        } else {\n                            builder.Append(\"\\\\u\");\n                            builder.Append(codepoint.ToString(\"x4\"));\n                        }\n                        break;\n                    }\n                }\n\n                builder.Append('\\\"');\n            }\n\n            void SerializeOther(object value) {\n                // NOTE: decimals lose precision during serialization.\n                // They always have, I'm just letting you know.\n                // Previously floats and doubles lost precision too.\n                if (value is float) {\n                    builder.Append(((float) value).ToString(\"R\"));\n                } else if (value is int\n                    || value is uint\n                    || value is long\n                    || value is sbyte\n                    || value is byte\n                    || value is short\n                    || value is ushort\n                    || value is ulong) {\n                    builder.Append(value);\n                } else if (value is double\n                    || value is decimal) {\n                    builder.Append(Convert.ToDouble(value).ToString(\"R\"));\n                } else {\n                    SerializeString(value.ToString());\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/AFMiniJSON.cs.meta",
    "content": "fileFormatVersion: 2\nguid: bc3d1c806d507463e9b560eb09d8eb0e\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AFPurchaseDetailsAndroid.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    public enum AFPurchaseType\n    {\n        Subscription = 0,\n        OneTimePurchase = 1\n    }\n\n    /// <summary>\n    /// Purchase details class matching Android SDK AFPurchaseDetails\n    /// </summary>\n    public class AFPurchaseDetailsAndroid\n    {\n        public AFPurchaseType purchaseType { get; private set; }\n        public string purchaseToken { get; private set; }\n        public string productId { get; private set; }\n\n        public AFPurchaseDetailsAndroid(AFPurchaseType type, String purchaseToken, String productId)\n        {\n            this.purchaseType = type;\n            this.purchaseToken = purchaseToken;\n            this.productId = productId;\n        }\n\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AFPurchaseDetailsAndroid.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d71b3864006f94ac08938b2ebdc940bc\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AFSDKPurchaseDetailsIOS.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    /// <summary>\n    /// Purchase type enum matching iOS SDK AFSDKPurchaseType\n    /// </summary>\n    public enum AFSDKPurchaseType\n    {\n        Subscription,\n        OneTimePurchase\n    }\n\n    /// <summary>\n    /// Purchase details class matching iOS SDK AFSDKPurchaseDetails\n    /// </summary>\n    public class AFSDKPurchaseDetailsIOS\n    {\n        public string productId { get; private set; }\n        public string transactionId { get; private set; }\n        public AFSDKPurchaseType purchaseType { get; private set; }\n\n        private AFSDKPurchaseDetailsIOS(string productId, string transactionId, AFSDKPurchaseType purchaseType)\n        {\n            this.productId = productId;\n            this.transactionId = transactionId;\n            this.purchaseType = purchaseType;\n        }\n\n        public static AFSDKPurchaseDetailsIOS Init(string productId, string transactionId, AFSDKPurchaseType purchaseType)\n        {\n            return new AFSDKPurchaseDetailsIOS(productId, transactionId, purchaseType);\n        }\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AFSDKPurchaseDetailsIOS.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 44bb6c4472701416080eb050732075ea\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AFSDKValidateAndLogResult.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    public enum AFSDKValidateAndLogStatus\n    {\n        AFSDKValidateAndLogStatusSuccess,\n        AFSDKValidateAndLogStatusFailure,\n        AFSDKValidateAndLogStatusError\n    }\n\n\n    /// <summary>\n    // \n    /// </summary>\n    public class AFSDKValidateAndLogResult\n    {\n        public AFSDKValidateAndLogStatus status { get; private set; }\n        public Dictionary<string, object> result { get; private set; }\n        public Dictionary<string, object> errorData { get; private set; }\n        public string error { get; private set; }\n\n        private AFSDKValidateAndLogResult(AFSDKValidateAndLogStatus status, Dictionary<string, object> result, Dictionary<string, object> errorData, string error)\n        {\n            this.status = status;\n            this.result = result;\n            this.errorData = errorData;\n            this.error = error;\n        }\n\n        public static AFSDKValidateAndLogResult Init(AFSDKValidateAndLogStatus status, Dictionary<string, object> result, Dictionary<string, object> errorData, string error)\n        {\n            return new AFSDKValidateAndLogResult(status, result, errorData, error);\n        }\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AFSDKValidateAndLogResult.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 2df1c6f1eab2e4849bf2762a8d78933f\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyer.asmdef",
    "content": "{\n    \"name\": \"AppsFlyer\",\n    \"references\": [],\n    \"includePlatforms\": [],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": false,\n    \"precompiledReferences\": [],\n    \"autoReferenced\": true,\n    \"defineConstraints\": [],\n    \"versionDefines\": [],\n    \"noEngineReferences\": false\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyer.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: 2a37df438292d4903b4e5159c5de3bf9\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace AppsFlyerSDK\n{\n    public class AppsFlyer : MonoBehaviour\n    {\n        public static readonly string kAppsFlyerPluginVersion = \"6.17.91\";\n        public static string CallBackObjectName = null;\n        private static EventHandler onRequestResponse;\n        private static EventHandler onInAppResponse;\n        private static EventHandler onDeepLinkReceived;\n        public static IAppsFlyerNativeBridge instance = null;\n        public delegate void unityCallBack(string message);\n\n\n        /// <summary>\n        /// Initialize the AppsFlyer SDK with your devKey and appID.\n        /// The dev key is required on all platforms, and the appID is required for iOS. \n        /// If you app is for Android only pass null for the appID.\n        /// </summary>\n        /// <param name=\"devKey\"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>\n        /// <param name=\"appID\">Your app's Apple ID.</param>\n        /// <example>\n        /// <code>\n        /// AppsFlyer.initSDK(\"K2***********99\", \"41*****44\"\");\n        /// </code>\n        /// </example>\n        public static void initSDK(string devKey, string appID)\n        {\n            initSDK(devKey, appID, null);\n        }\n\n        /// <summary>\n        /// Initialize the AppsFlyer SDK with your devKey and appID.\n        /// The dev key is required on all platforms, and the appID is required for iOS. \n        /// If you app is for Android only pass null for the appID.\n        /// </summary>\n        /// <param name=\"devKey\"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>\n        /// <param name=\"appID\">Your app's Apple ID.</param>\n        /// <param name=\"gameObject\">pass the script of the game object being used.</param>\n        /// <example>\n        /// <code>\n        /// AppsFlyer.initSDK(\"K2***********99\", 41*****44, this);\n        /// </code>\n        /// </example>\n        public static void initSDK(string devKey, string appID, MonoBehaviour gameObject)\n        {\n\n            if (gameObject != null)\n            {\n#if UNITY_STANDALONE_OSX\n                CallBackObjectName = gameObject.GetType().ToString();\n#else\n                CallBackObjectName = gameObject.name;\n#endif\n            }\n\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n            if (instance == null || !instance.isInit)\n            {\n                instance = new AppsFlyeriOS(devKey, appID, gameObject);\n                instance.isInit = true;\n            }\n#elif UNITY_ANDROID\n            if (instance == null || !instance.isInit)\n            {\n                AppsFlyerAndroid appsFlyerAndroid = new AppsFlyerAndroid();\n                appsFlyerAndroid.initSDK(devKey, gameObject);\n                instance = appsFlyerAndroid;\n                instance.isInit = true;\n                \n            }\n#elif UNITY_WSA_10_0\n            AppsFlyerWindows.InitSDK(devKey, appID, gameObject);\n            if (gameObject != null)\n            {\n                AppsFlyerWindows.GetConversionData(gameObject.name);\n            }\n#else\n\n#endif\n        }\n\n\n        /// <summary>\n        /// Once this API is invoked, our SDK will start.\n        /// Once the API is called a sessions will be immediately sent, and all background forground transitions will send a session.\n        /// </summary>\n        public static void startSDK()\n        {\n#if UNITY_WSA_10_0\n              AppsFlyerWindows.Start();\n           \n#else\n            if (instance != null)\n            {\n                instance.startSDK(onRequestResponse != null, CallBackObjectName);\n            }\n#endif\n        }\n\n        \n  \n\n     \n\n        /// <summary>\n        /// Send an In-App Event.\n        /// In-App Events provide insight on what is happening in your app.\n        /// </summary>\n        /// <param name=\"eventName\">Event Name as String.</param>\n        /// <param name=\"eventValues\">Event Values as Dictionary.</param>\n        public static void sendEvent(string eventName, Dictionary<string, string> eventValues)\n        {\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n            AppsFlyerWindows.LogEvent(eventName, eventValues);\n#else\n            if (instance != null)\n            {\n                instance.sendEvent(eventName, eventValues, onInAppResponse != null, CallBackObjectName);\n            }\n#endif\n        }\n        /// <summary>\n        /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.\n        /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance.\n        /// This can be achieved with the stopSDK API.\n        /// </summary>\n        /// <param name=\"isSDKStopped\"> should sdk be stopped.</param>\n        public static void stopSDK(bool isSDKStopped)\n        {\n            if (instance != null)\n            {\n                instance.stopSDK(isSDKStopped);\n            }\n        }\n\n        // <summary>\n        /// Was the stopSDK(boolean) API set to true.\n        /// </summary>\n        /// <returns>boolean isSDKStopped.</returns>\n        public static bool isSDKStopped()\n        {\n            if (instance != null)\n            {\n                return instance.isSDKStopped();\n            }\n\n            return false;\n        }\n\n        /// <summary>\n        /// Get the AppsFlyer SDK version used in app.\n        /// </summary>\n        /// <returns>The current SDK version.</returns>\n        public static string getSdkVersion()\n        {\n            if (instance != null)\n            {\n                return instance.getSdkVersion();\n            }\n\n            return \"\";\n\n        }\n\n        /// <summary>\n        /// Enables Debug logs for the AppsFlyer SDK.\n        /// Should only be set to true in development / debug.\n        /// </summary>\n        /// <param name=\"shouldEnable\">shouldEnable boolean.</param>\n        public static void setIsDebug(bool shouldEnable)\n        {\n            if (instance != null)\n            {\n                instance.setIsDebug(shouldEnable);\n            } else {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n                instance = new AppsFlyeriOS();\n                instance.setIsDebug(shouldEnable);\n#elif UNITY_ANDROID\n                instance = new AppsFlyerAndroid();\n                instance.setIsDebug(shouldEnable);\n#else\n\n#endif\n            }\n\n        }\n\n        /// <summary>\n        /// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs.\n        /// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs.\n        /// </summary>\n        /// <param name=\"id\">Customer ID for client.</param>\n        public static void setCustomerUserId(string id)\n        {\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n             AppsFlyerWindows.SetCustomerUserId(id);\n#else\n            if (instance != null)\n            {\n                instance.setCustomerUserId(id);\n            }\n#endif\n        }\n\n        /// <summary>\n        /// Set the OneLink ID that should be used for User-Invite-API.\n        /// The link that is generated for the user invite will use this OneLink as the base link.\n        /// </summary>\n        /// <param name=\"oneLinkId\">OneLink ID obtained from the AppsFlyer Dashboard.</param>\n        public static void setAppInviteOneLinkID(string oneLinkId)\n        {\n\n            if (instance != null)\n            {\n                instance.setAppInviteOneLinkID(oneLinkId);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Set the deepLink timeout value that should be used for DDL.\n        /// </summary>\n        /// <param name=\"deepLinkTimeout\">deepLink timeout in milliseconds.</param>\n        public static void setDeepLinkTimeout(long deepLinkTimeout)\n        {\n\n            if (instance != null)\n            {\n                instance.setDeepLinkTimeout(deepLinkTimeout);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Set additional data to be sent to AppsFlyer.\n        /// </summary>\n        /// <param name=\"customData\">additional data Dictionary.</param>\n        public static void setAdditionalData(Dictionary<string, string> customData)\n        {\n\n            if (instance != null)\n            {\n                instance.setAdditionalData(customData);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Advertisers can wrap AppsFlyer OneLink within another Universal Link.\n        /// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer.\n        /// </summary>\n        /// <param name=\"urls\">Array of urls.</param>\n        public static void setResolveDeepLinkURLs(params string[] urls)\n        {\n\n            if (instance != null)\n            {\n                instance.setResolveDeepLinkURLs(urls);\n            }\n\n\n        }\n\n\n        /// <summary>\n        /// Advertisers can use this method to set vanity onelink domains.\n        /// </summary>\n        /// <param name=\"domains\">Array of domains.</param>\n        public static void setOneLinkCustomDomain(params string[] domains)\n        {\n            \n            if (instance != null)\n            {\n                instance.setOneLinkCustomDomain(domains);\n            }\n            else\n            {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n                instance = new AppsFlyeriOS();\n#elif UNITY_ANDROID\n                instance = new AppsFlyerAndroid();\n#else\n\n#endif\n\n                \n\n            }\n        }\n\n        /// <summary>\n        /// Setting user local currency code for in-app purchases.\n        /// The currency code should be a 3 character ISO 4217 code. (default is USD).\n        /// You can set the currency code for all events by calling the following method.\n        /// </summary>\n        /// <param name=\"currencyCode\">3 character ISO 4217 code.</param>\n        public static void setCurrencyCode(string currencyCode)\n        {\n\n            if (instance != null)\n            {\n                instance.setCurrencyCode(currencyCode);\n            } else {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n                instance = new AppsFlyeriOS();\n                instance.setCurrencyCode(currencyCode);\n#elif UNITY_ANDROID\n                instance = new AppsFlyerAndroid();\n                instance.setCurrencyCode(currencyCode);\n#else\n#endif\n        }\n        }\n\n        /// <summary>\n        /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application.\n        /// </summary>\n        /// <param name = \"appsFlyerConsent\" >instance of AppsFlyerConsent.</param>\n        public static void setConsentData(AppsFlyerConsent appsFlyerConsent)\n        {\n            if (instance != null)\n            {\n                instance.setConsentData(appsFlyerConsent);\n            }\n        }\n\n        /// <summary>\n        /// Logs ad revenue data along with additional parameters if provided.\n        /// </summary>\n        /// <param name = \"adRevenueData\" >instance of AFAdRevenueData containing ad revenue information.</param>\n        /// <param name = \"additionalParameters\" >An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters.</param>\n        public static void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters)\n        {\n            if (instance != null)\n            {\n                instance.logAdRevenue(adRevenueData, additionalParameters);\n            }\n        }\n\n        /// <summary>\n        /// Manually record the location of the user.\n        /// </summary>\n        /// <param name=\"latitude\">latitude as double.</param>\n        /// <param name=\"longitude\">longitude as double.</param>\n        public static void recordLocation(double latitude, double longitude)\n        {\n\n            if (instance != null)\n            {\n                instance.recordLocation(latitude, longitude);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Anonymize user Data.\n        /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions.\n        /// Default is false.\n        /// </summary>\n        /// <param name = \"shouldAnonymizeUser\" >shouldAnonymizeUser boolean.</param>\n        public static void anonymizeUser(bool shouldAnonymizeUser)\n        {\n\n            if (instance != null)\n            {\n                instance.anonymizeUser(shouldAnonymizeUser);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data.\n        /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it.\n        /// </summary>\n        /// <param name = \"shouldCollectTcfData\" >should start TCF Data collection boolean.</param>\n        public static void enableTCFDataCollection(bool shouldCollectTcfData)\n        {\n            if (instance != null)\n            {\n                instance.enableTCFDataCollection(shouldCollectTcfData);\n            }\n        }\n\n        /// <summary>\n        /// Get AppsFlyer's unique device ID which is created for every new install of an app.\n        /// </summary>\n        /// <returns>AppsFlyer's unique device ID.</returns>\n        public static string getAppsFlyerId()\n        {\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n            return AppsFlyerWindows.GetAppsFlyerId();\n#else\n            if (instance != null)\n            {\n                return instance.getAppsFlyerId();\n            }\n#endif\n            return string.Empty;\n\n        }\n\n        /// <summary>\n        /// Set a custom value for the minimum required time between sessions.\n        /// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions.\n        /// </summary>\n        /// <param name=\"seconds\">minimum time between 2 separate sessions in seconds.</param>\n        public static void setMinTimeBetweenSessions(int seconds)\n        {\n\n            if (instance != null)\n            {\n                instance.setMinTimeBetweenSessions(seconds);\n            }\n\n\n        }\n\n        /// <summary>\n        /// Set a custom host.\n        /// </summary>\n        /// <param name=\"hostPrefixName\">Host prefix.</param>\n        /// <param name=\"hostName\">Host name.</param>\n        public static void setHost(string hostPrefixName, string hostName)\n        {\n\n            if (instance != null)\n            {\n                instance.setHost(hostPrefixName, hostName);\n            } else {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n                instance = new AppsFlyeriOS();\n                instance.setHost(hostPrefixName, hostName);\n#elif UNITY_ANDROID\n                instance = new AppsFlyerAndroid();\n                instance.setHost(hostPrefixName, hostName);\n#else\n#endif\n        }\n        }\n\n        /// <summary>\n        /// Set the user emails and encrypt them.\n        /// cryptMethod Encryption method:\n        /// EmailCryptType.EmailCryptTypeMD5\n        /// EmailCryptType.EmailCryptTypeSHA1\n        /// EmailCryptType.EmailCryptTypeSHA256\n        /// EmailCryptType.EmailCryptTypeNone\n        /// </summary>\n        /// <param name=\"cryptMethod\">Encryption method.</param>\n        /// <param name=\"emails\">User emails.</param>\n        public static void setUserEmails(EmailCryptType cryptType, params string[] userEmails)\n        {\n\n            if (instance != null)\n            {\n                instance.setUserEmails(cryptType, userEmails);\n            }\n\n        }\n\n        public static void updateServerUninstallToken(string token)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.updateServerUninstallToken(token);\n            }\n        }\n\n        /// <summary>\n        /// Set the user phone number.\n        /// </summary>\n        /// <param name=\"phoneNumber\">phoneNumber string</param>\n        public static void setPhoneNumber(string phoneNumber)\n        {\n\n            if (instance != null)\n            {\n                instance.setPhoneNumber(phoneNumber);\n            }\n\n        }\n\n        public static void setImeiData(string aImei)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setImeiData(aImei);\n            }\n        }\n\n        /// <summary>\n        /// Used by advertisers to exclude all networks/integrated partners from getting data.\n        /// </summary>\n        [Obsolete(\"Please use setSharingFilterForPartners api\")]\n        public static void setSharingFilterForAllPartners()\n        {\n\n            if (instance != null)\n            {\n                instance.setSharingFilterForAllPartners();\n            }\n\n\n        }\n\n        public static void setAndroidIdData(string aAndroidId)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setAndroidIdData(aAndroidId);\n            }\n        }\n\n        public static void waitForCustomerUserId(bool wait)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.waitForCustomerUserId(wait);\n            }\n        }\n\n        /// <summary>\n        /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.\n        /// </summary>\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        [Obsolete(\"Please use setSharingFilterForPartners api\")]\n        public static void setSharingFilter(params string[] partners)\n        {\n\n            if (instance != null)\n            {\n                instance.setSharingFilter(partners);\n            }\n\n\n        }\n\n        public static void setCustomerIdAndStartSDK(string id)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setCustomerIdAndStartSDK(id);\n            }\n        }\n\n        /// <summary>\n        /// Lets you configure how which partners should the SDK exclude from data-sharing.\n        /// </summary>\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        public static void setSharingFilterForPartners(params string[] partners)\n        {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n            AppsFlyeriOS.setSharingFilterForPartners(partners);\n#elif UNITY_ANDROID\n            AppsFlyerAndroid.setSharingFilterForPartners(partners);\n#else\n\n#endif\n        }\n\n        public static string getOutOfStore()\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                return appsFlyerAndroidInstance.getOutOfStore();\n            }\n            return string.Empty;\n        }\n\n        public static void setOutOfStore(string sourceName)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setOutOfStore(sourceName);\n            }\n        }\n\n        /// <summary>\n        /// Register a Conversion Data Listener.\n        /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level.\n        /// By doing this you can serve users with personalized content or send them to specific activities within the app,\n        /// which can greatly enhance their engagement with your app.\n        /// </summary>\n        /// <example>\n        /// <code>\n        /// AppsFlyer.getConversionData(this.name);\n        /// </code>\n        /// </example>\n        public static void getConversionData(string objectName)\n        {\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n            AppsFlyerWindows.GetConversionData(\"\");\n#else\n            if (instance != null)\n            {\n                instance.getConversionData(objectName);\n            }\n#endif\n\n        }\n\n        public static void setCollectAndroidID(bool isCollect)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setCollectAndroidID(isCollect);\n            }\n        }\n\n        public static void setIsUpdate(bool isUpdate)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setIsUpdate(isUpdate);\n            }\n        }\n\n        public static void setCollectIMEI(bool isCollect)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setCollectIMEI(isCollect);\n            }\n        }\n\n        public static void setDisableCollectAppleAdSupport(bool disable)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setDisableCollectAppleAdSupport(disable);\n            }\n        }\n\n        public static void setShouldCollectDeviceName(bool shouldCollectDeviceName)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setShouldCollectDeviceName(shouldCollectDeviceName);\n            }\n        }\n\n\n        /// <summary>\n        /// Use the following API to attribute the click and launch the app store's app page.\n        /// </summary>\n        /// <param name=\"appID\">promoted App ID</param>\n        /// <param name=\"campaign\">cross promotion campaign</param>\n        /// <param name=\"userParams\">additional user params</param>\n        /// <example>\n        /// <code>\n        /// Dictionary<string, string> parameters = new Dictionary<string, string>();\n        /// parameters.Add(\"af_sub1\", \"val\");\n        /// parameters.Add(\"custom_param\", \"val2\");\n        /// AppsFlyer.attributeAndOpenStore(\"123456789\", \"test campaign\", parameters, this);\n        /// </code>\n        /// </example>\n        public static void attributeAndOpenStore(string appID, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject)\n        {\n\n            if (instance != null)\n            {\n                instance.attributeAndOpenStore(appID, campaign, userParams, gameObject);\n            }\n            \n        }\n\n        public static void setPreinstallAttribution(string mediaSource, string campaign, string siteId)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setPreinstallAttribution(mediaSource, campaign, siteId);\n            }\n        }\n\n        public static void setDisableCollectIAd(bool disableCollectIAd)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setDisableCollectIAd(disableCollectIAd);\n            }\n        }\n\n        public static bool isPreInstalledApp()\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                return appsFlyerAndroidInstance.isPreInstalledApp();\n            }\n            return false;\n        }\n\n        public static void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setUseReceiptValidationSandbox(useReceiptValidationSandbox);\n            }\n        }\n\n        /// <summary>\n        /// To attribute an impression use the following API call.\n        /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.\n        /// </summary>\n        /// <param name=\"appID\">promoted App ID.</param>\n        /// <param name=\"campaign\">cross promotion campaign.</param>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public static void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters)\n        {\n\n            if (instance != null)\n            {\n                instance.recordCrossPromoteImpression(appID, campaign, parameters);\n            }\n            \n        }\n\n        public static void setUseUninstallSandbox(bool useUninstallSandbox)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setUseUninstallSandbox(useUninstallSandbox);\n            }\n        }\n\n        public static string getAttributionId()\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                return appsFlyerAndroidInstance.getAttributionId();\n            }\n            return string.Empty;\n        }\n\n        public static void handlePushNotifications()\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.handlePushNotifications();\n            }\n        }\n\n        /// <summary>\n        /// [Deprecated] Validates an in-app purchase on iOS.\n        /// Use the V2 overload with AFSDKPurchaseDetailsIOS instead.\n        /// </summary>\n        [System.Obsolete(\"This method is deprecated. Use validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject) instead.\")]\n        public static void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.validateAndSendInAppPurchase(productIdentifier, price, currency, transactionId, additionalParameters, gameObject);\n            }\n        }\n\n        /// <summary>\n        /// Validates an in-app purchase on iOS using the V2 API.\n        /// </summary>\n        public static void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.validateAndSendInAppPurchase(details, purchaseAdditionalDetails, gameObject);\n            }\n        }\n\n        /// <summary>\n        /// [Deprecated] Validates an in-app purchase on Android.\n        /// Use the V2 overload with AFPurchaseDetailsAndroid instead.\n        /// </summary>\n        [System.Obsolete(\"This method is deprecated. Use validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject) instead.\")]\n        public static void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.validateAndSendInAppPurchase(publicKey, signature,purchaseData, price, currency, additionalParameters, gameObject);\n            }\n        }\n\n        /// <summary>\n        /// Validates an in-app purchase on Android using the V2 API.\n        /// </summary>\n        public static void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.validateAndSendInAppPurchase(details, purchaseAdditionalDetails, gameObject);\n            }\n        }\n\n        public static void handleOpenUrl(string url, string sourceApplication, string annotation)\n        { \n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.handleOpenUrl(url, sourceApplication, annotation);\n            }\n        }\n\n        public static void registerUninstall(byte[] deviceToken)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.registerUninstall(deviceToken);\n            }\n        }\n\n        public static void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.waitForATTUserAuthorizationWithTimeoutInterval(timeoutInterval);\n            }\n        }\n\n        public static void setCurrentDeviceLanguage(string language)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.setCurrentDeviceLanguage(language);\n            }\n        }\n\n        /// <summary>\n        /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click.\n        /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution-\n        /// </summary>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public static void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject)\n        {\n\n            if (instance != null)\n            {\n                instance.generateUserInviteLink(parameters, gameObject);\n            }\n            \n        }\n\n        public static void disableSKAdNetwork(bool isDisabled)\n        {\n            if (instance != null && instance is IAppsFlyerIOSBridge)\n            {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.disableSKAdNetwork(isDisabled);\n            } else {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n                instance = new AppsFlyeriOS();\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.disableSKAdNetwork(isDisabled);\n#else\n#endif\n        }\n        }\n\n        public static void setCollectOaid(bool isCollect)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setCollectOaid(isCollect);\n            }\n        }\n\n\n        /// <summary>\n        /// Use this method if you’re integrating your app with push providers \n        /// that don’t use the default push notification JSON schema the SDK expects.\n        /// See docs for more info.\n        /// </summary>\n        /// <param name=\"paths\">array of nested json path</param>\n        public static void addPushNotificationDeepLinkPath(params string[] paths)\n        {\n\n            if (instance != null)\n            {\n                instance.addPushNotificationDeepLinkPath(paths);\n            }\n\n        }\n\n        public static void setDisableAdvertisingIdentifiers(bool disable)\n        {\n            if (instance != null && instance is IAppsFlyerAndroidBridge)\n            {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setDisableAdvertisingIdentifiers(disable);\n            }\n        }\n\n        /// <summary>\n        /// Subscribe for unified deeplink API.\n        /// This is called automatically from OnDeepLinkReceived.\n        /// CallBackObjectName is set in the init method.\n        /// </summary>\n        public static void subscribeForDeepLink()\n        {\n\n            if (instance != null)\n            {\n                instance.subscribeForDeepLink(CallBackObjectName);\n            }\n\n        }\n\n        /// <summary>\n        /// Allows sending custom data for partner integration purposes.\n        /// partnerId : id of the partner\n        /// partnerInfo: customer data\n        /// </summary>\n        public static void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo)\n        {\n            if (instance != null)\n            {\n                instance.setPartnerData(partnerId, partnerInfo);\n            }\n\n        }\n\n        /// <summary>\n        /// Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device.\n        /// </summary>\n        public static void setDisableNetworkData(bool disable) {\n            if (instance != null && instance is IAppsFlyerAndroidBridge) {\n                IAppsFlyerAndroidBridge appsFlyerAndroidInstance = (IAppsFlyerAndroidBridge)instance;\n                appsFlyerAndroidInstance.setDisableNetworkData(disable);\n            }\n        }\n\n\n        /// <summary>\n        /// Use to disable app vendor identifier (IDFV) collection, 'true' to disable.\n        /// </summary>\n        public static void disableIDFVCollection(bool isDisabled) \n        {\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n            if (instance == null) { \n                instance = new AppsFlyeriOS();\n            }\n            if (instance != null && instance is IAppsFlyerIOSBridge) {\n                IAppsFlyerIOSBridge appsFlyeriOSInstance = (IAppsFlyerIOSBridge)instance;\n                appsFlyeriOSInstance.disableIDFVCollection(isDisabled);\n            }\n#else\n#endif\n        }\n\n        /// <summary>\n        /// Start callback event.\n        /// </summary>\n        public static event EventHandler OnRequestResponse\n        {\n            add\n            {\n                onRequestResponse += value;\n            }  \n            remove  \n            {  \n                onRequestResponse -= value;\n            }     \n        }\n        \n        /// <summary>\n        /// In-App callback event.\n        /// </summary>\n        public static event EventHandler OnInAppResponse\n        {\n            add\n            {\n                onInAppResponse += value;\n            }  \n            remove  \n            {  \n                onInAppResponse -= value;\n            }     \n        }\n\n        /// <summary>\n        /// Unified DeepLink Event\n        /// </summary>\n        public static event EventHandler OnDeepLinkReceived\n        {\n            add\n            {\n                onDeepLinkReceived += value;\n                subscribeForDeepLink();\n            }  \n            remove  \n            {  \n                onDeepLinkReceived -= value;\n            }     \n        }\n\n        /// <summary>\n        /// Used to accept start callback from UnitySendMessage on native side.\n        /// </summary>\n        public void inAppResponseReceived(string response)\n        {\n            if (onInAppResponse != null) \n            {\n                onInAppResponse.Invoke(null, parseRequestCallback(response));\n            }\n        }\n        \n        /// <summary>\n        /// Used to accept in-app callback from UnitySendMessage on native side.\n        /// </summary>\n        public void requestResponseReceived(string response)\n        {\n            if (onRequestResponse != null)\n            {\n                onRequestResponse.Invoke(null, parseRequestCallback(response));\n            }\n        }\n\n        /// <summary>\n        /// Used to accept deeplink callback from UnitySendMessage on native side.\n        /// </summary>\n        public void onDeepLinking(string response)\n        {\n\n            DeepLinkEventsArgs args = new DeepLinkEventsArgs(response);\n\n            if (onDeepLinkReceived != null)\n            {\n                onDeepLinkReceived.Invoke(null, args);\n            }\n        }\n\n        private static AppsFlyerRequestEventArgs parseRequestCallback(string response)\n        {\n            int responseCode = 0;\n            string errorDescription = \"\";\n            \n            try\n            {\n                Dictionary<string, object> dictionary = CallbackStringToDictionary(response);\n                var errorResponse = dictionary.ContainsKey(\"errorDescription\") ? dictionary[\"errorDescription\"] : \"\";\n                errorDescription = (string)errorResponse;\n                responseCode = (int)(long) dictionary[\"statusCode\"];\n            }\n            catch (Exception e)\n            {\n                AFLog(\"parseRequestCallback\", String.Format(\"{0} Exception caught.\", e));\n            }\n\n            return new AppsFlyerRequestEventArgs(responseCode, errorDescription);\n        }\n\n        /// <summary>\n        /// Helper method to convert json strings to dictionary.\n        /// </summary>\n        /// <param name=\"str\">json string</param>\n        /// <returns>dictionary representing the input json string.</returns>\n        public static Dictionary<string, object> CallbackStringToDictionary(string str)\n        {\n            return AFMiniJSON.Json.Deserialize(str) as Dictionary<string, object>;\n        }\n\n        /// <summary>\n        /// Helper method to log AppsFlyer events and callbacks.\n        /// </summary>\n        /// <param name=\"methodName\">method name</param>\n        /// <param name=\"str\">message to log</param>\n        public static void AFLog(string methodName, string str)\n        {\n            Debug.Log(string.Format(\"AppsFlyer_Unity_v{0} {1} called with {2}\", kAppsFlyerPluginVersion, methodName, str));\n        }\n    }\n\n    public enum EmailCryptType\n    {\n        // None\n        EmailCryptTypeNone = 0,\n        // SHA256\n        EmailCryptTypeSHA256 = 1,\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 45161025a517d427381d3d06153a5ad3\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerAndroid.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace AppsFlyerSDK\n{\n\n#if UNITY_ANDROID \n    public class AppsFlyerAndroid : IAppsFlyerAndroidBridge\n    {\n        public bool isInit { get; set; }\n\n        private static AndroidJavaClass appsFlyerAndroid = new AndroidJavaClass(\"com.appsflyer.unity.AppsFlyerAndroidWrapper\");\n\n        public AppsFlyerAndroid() { }\n\n        /// <summary>\n        /// Use this method to init the sdk for the application.\n        /// Call this method before startSDK.\n        /// </summary>\n        /// <param name=\"devkey\"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>\n        /// <param name=\"gameObject\">The current game object. This is used to get the conversion data callbacks. Pass null if you do not need the callbacks.</param>\n        public void initSDK(string devkey, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"initSDK\", devkey, gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// Use this method to start the sdk for the application.\n        /// The AppsFlyer's Dev-Key must be provided.\n        /// </summary>\n        /// <param name=\"devkey\"> AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>\n        public void startSDK(bool onRequestResponse, string CallBackObjectName)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"startTracking\", onRequestResponse, CallBackObjectName);\n#endif\n        }\n\n        /// <summary>\n        /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.\n        /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance.\n        /// This can be achieved with the stopSDK API.\n        /// </summary>\n        /// <param name=\"isSDKStopped\">boolean should SDK be stopped.</param>\n        public void stopSDK(bool isSDKStopped)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"stopTracking\", isSDKStopped);\n#endif\n        }\n\n        /// <summary>\n        /// Get the AppsFlyer SDK version used in app.\n        /// </summary>\n        /// <returns>AppsFlyer SDK version.</returns>\n        public string getSdkVersion()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getSdkVersion\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Manually pass the Firebase / GCM Device Token for Uninstall measurement.\n        /// </summary>\n        /// <param name=\"token\">Firebase Device Token.</param>\n        public void updateServerUninstallToken(string token)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"updateServerUninstallToken\", token);\n#endif\n        }\n\n        /// <summary>\n        /// Enables Debug logs for the AppsFlyer SDK.\n        /// Should only be set to true in development / debug.\n        /// </summary>\n        /// <param name=\"shouldEnable\">shouldEnable boolean.</param>\n        public void setIsDebug(bool shouldEnable)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setIsDebug\", shouldEnable);\n#endif\n        }\n\n        /// <summary>\n        /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4)\n        /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).\n        /// Use this API to explicitly send IMEI to AppsFlyer.\n        /// </summary>\n        /// <param name=\"aImei\">device's IMEI.</param>\n        public void setImeiData(string aImei)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setImeiData\", aImei);\n#endif\n        }\n\n        /// <summary>\n        /// By default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat(4.4)\n        /// and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).\n        /// Use this API to explicitly send Android ID to AppsFlyer.\n        /// </summary>\n        /// <param name=\"aAndroidId\">device's Android ID.</param>\n        public void setAndroidIdData(string aAndroidId)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setAndroidIdData\", aAndroidId);\n#endif\n        }\n\n        /// <summary>\n        /// Setting your own customer ID enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs.\n        /// This ID is available in AppsFlyer CSV reports along with Postback APIs for cross-referencing with your internal IDs.\n        /// </summary>\n        /// <param name=\"id\">Customer ID for client.</param>\n        public void setCustomerUserId(string id)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCustomerUserId\", id);\n#endif\n        }\n\n        /// <summary>\n        /// It is possible to delay the SDK Initialization until the customerUserID is set.\n        /// This feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided.\n        /// If this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided.\n        /// </summary>\n        /// <param name=\"wait\">wait boolean.</param>\n        public void waitForCustomerUserId(bool wait)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"waitForCustomerUserId\", wait);\n#endif\n        }\n\n        /// <summary>\n        /// Use this API to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal activity.\n        /// </summary>\n        /// <param name=\"id\">Customer ID for client.</param>\n        public void setCustomerIdAndStartSDK(string id)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCustomerIdAndTrack\", id);\n#endif\n        }\n\n        /// <summary>\n        /// Get the current AF_STORE value.\n        /// </summary>\n        /// <returns>AF_Store value.</returns>\n        public string getOutOfStore()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getOutOfStore\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Manually set the AF_STORE value.\n        /// </summary>\n        /// <param name=\"sourceName\">value to be set.</param>\n        public void setOutOfStore(string sourceName)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setOutOfStore\", sourceName);\n#endif\n        }\n\n        /// <summary>\n        /// Set the OneLink ID that should be used for User-Invites.\n        /// The link that is generated for the user invite will use this OneLink as the base link.\n        /// </summary>\n        /// <param name=\"oneLinkId\">OneLink ID obtained from the AppsFlyer Dashboard.</param>\n        public void setAppInviteOneLinkID(string oneLinkId)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setAppInviteOneLinkID\", oneLinkId);\n#endif\n        }\n\n        /// <summary>\n        /// Set additional data to be sent to AppsFlyer.\n        /// </summary>\n        /// <param name=\"customData\">additional data Dictionary.</param>\n        public void setAdditionalData(Dictionary<string, string> customData)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setAdditionalData\", convertDictionaryToJavaMap(customData));\n#endif\n        }\n\n        //// <summary>\n        /// Set the deepLink timeout value that should be used for DDL.\n        /// </summary>\n        /// <param name=\"deepLinkTimeout\">deepLink timeout in milliseconds.</param>\n        public void setDeepLinkTimeout(long deepLinkTimeout)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"setDeepLinkTimeout\", deepLinkTimeout);\n#endif\n        }\n\n        /// <summary>\n        /// Set the user emails.\n        /// </summary>\n        /// <param name=\"emails\">User emails.</param>\n        public void setUserEmails(params string[] userEmails)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setUserEmails\", (object)userEmails);\n#endif\n        }\n\n\n        /// <summary>\n        /// Set the user phone number.\n        /// </summary>\n        /// <param name=\"phoneNumber\">User phoneNumber.</param>\n        public void setPhoneNumber(string phoneNumber){\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setPhoneNumber\", phoneNumber);\n#endif\n        }\n\n        /// <summary>\n        /// Set the user emails and encrypt them.\n        /// cryptMethod Encryption method:\n        /// EmailCryptType.EmailCryptTypeMD5\n        /// EmailCryptType.EmailCryptTypeSHA1\n        /// EmailCryptType.EmailCryptTypeSHA256\n        /// EmailCryptType.EmailCryptTypeNone\n        /// </summary>\n        /// <param name=\"cryptMethod\">Encryption method.</param>\n        /// <param name=\"emails\">User emails.</param>\n        public void setUserEmails(EmailCryptType cryptMethod, params string[] emails)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setUserEmails\", getEmailType(cryptMethod), (object)emails);\n#endif\n        }\n\n        /// <summary>\n        /// Opt-out of collection of Android ID.\n        /// If the app does NOT contain Google Play Services, Android ID is collected by the SDK.\n        /// However, apps with Google play services should avoid Android ID collection as this is in violation of the Google Play policy.\n        /// </summary>\n        /// <param name=\"isCollect\">boolean, false to opt-out.</param>\n        public void setCollectAndroidID(bool isCollect)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCollectAndroidID\", isCollect);\n#endif\n        }\n\n        /// <summary>\n        /// Opt-out of collection of IMEI.\n        /// If the app does NOT contain Google Play Services, device IMEI is collected by the SDK.\n        /// However, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy.\n        /// </summary>\n        /// <param name=\"isCollect\">boolean, false to opt-out.</param>\n        public void setCollectIMEI(bool isCollect)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCollectIMEI\", isCollect);\n#endif\n        }\n\n        /// <summary>\n        /// Advertisers can wrap AppsFlyer OneLink within another Universal Link.\n        /// This Universal Link will invoke the app but any deep linking data will not propagate to AppsFlyer.\n        /// </summary>\n        /// <param name=\"urls\">Array of urls.</param>\n        public void setResolveDeepLinkURLs(params string[] urls)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"setResolveDeepLinkURLs\", (object)urls);\n#endif\n        }\n\n\n        /// <summary>\n        /// Advertisers can use this method to set vanity onelink domains.\n        /// </summary>\n        /// <param name=\"domains\">Array of domains.</param>\n        public void setOneLinkCustomDomain(params string[] domains)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setOneLinkCustomDomain\", (object)domains);\n#endif\n        }\n\n        /// <summary>\n        /// Manually set that the application was updated.\n        /// </summary>\n        /// <param name=\"isUpdate\">isUpdate boolean value.</param>\n        public void setIsUpdate(bool isUpdate)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setIsUpdate\", isUpdate);\n#endif\n        }\n\n        /// <summary>\n        /// Setting user local currency code for in-app purchases.\n        /// The currency code should be a 3 character ISO 4217 code. (default is USD).\n        /// You can set the currency code for all events by calling the following method.\n        /// </summary>\n        /// <param name=\"currencyCode\">3 character ISO 4217 code.</param>\n        public void setCurrencyCode(string currencyCode)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCurrencyCode\", currencyCode);\n#endif\n        }\n\n        /// <summary>\n        /// Manually record the location of the user.\n        /// </summary>\n        /// <param name=\"latitude\">latitude as double.</param>\n        /// <param name=\"longitude\">longitude as double.</param>\n        public void recordLocation(double latitude, double longitude)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"trackLocation\", latitude, longitude);\n#endif\n        }\n\n        /// <summary>\n        /// Send an In-App Event.\n        /// In-App Events provide insight on what is happening in your app.\n        /// </summary>\n        /// <param name=\"eventName\">Event Name as String.</param>\n        /// <param name=\"eventValues\">Event Values as Dictionary.</param>\n        public void sendEvent(string eventName, Dictionary<string, string> eventValues)\n        {\n            sendEvent(eventName, eventValues, false, AppsFlyer.CallBackObjectName);\n        }\n        \n        public void sendEvent(string eventName, Dictionary<string, string> eventValues, bool shouldCallback, string callBackObjectName)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"trackEvent\", eventName, convertDictionaryToJavaMap(eventValues), shouldCallback, callBackObjectName);\n#endif\n        }\n\n        /// <summary>\n        /// Anonymize user Data.\n        /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions.\n        /// Default is false.\n        /// </summary>\n        /// <param name=\"isDisabled\">isDisabled boolean.</param>\n        public void anonymizeUser(bool isDisabled)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"setDeviceTrackingDisabled\", isDisabled);\n#endif\n        }\n\n        /// <summary>\n        /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data.\n        /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it.\n        /// </summary>\n        /// <param name = \"shouldCollectTcfData\" >should start TCF Data collection boolean.</param>\n        public void enableTCFDataCollection(bool shouldCollectTcfData)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"enableTCFDataCollection\", shouldCollectTcfData);\n#endif\n        }\n\n        /// <summary>\n        /// Enable the collection of Facebook Deferred AppLinks.\n        /// Requires Facebook SDK and Facebook app on target/client device.\n        /// This API must be invoked prior to initializing the AppsFlyer SDK in order to function properly.\n        /// </summary>\n        /// <param name=\"isEnabled\">should Facebook's deferred app links be processed by the AppsFlyer SDK.</param>\n        public void enableFacebookDeferredApplinks(bool isEnabled)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"enableFacebookDeferredApplinks\", isEnabled);\n#endif\n        }\n\n        /// <summary>\n        /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application.\n        /// call this method when GDPR user is true\n        /// </summary>\n        /// <param name = \"hasConsentForDataUsage\" >hasConsentForDataUsage boolean.</param>\n        /// <param name = \"hasConsentForAdsPersonalization\" >hasConsentForAdsPersonalization boolean.</param>\n        public void setConsentData(AppsFlyerConsent appsFlyerConsent)\n        {\n#if !UNITY_EDITOR\n           string isUserSubjectToGDPR = appsFlyerConsent.isUserSubjectToGDPR?.ToString().ToLower() ?? \"null\";\n           string hasConsentForDataUsage = appsFlyerConsent.hasConsentForDataUsage?.ToString().ToLower() ?? \"null\";\n           string hasConsentForAdsPersonalization = appsFlyerConsent.hasConsentForAdsPersonalization?.ToString().ToLower() ?? \"null\";\n           string hasConsentForAdStorage = appsFlyerConsent.hasConsentForAdStorage?.ToString().ToLower() ?? \"null\";\n\n           appsFlyerAndroid.CallStatic(\"setConsentData\", isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization, hasConsentForAdStorage);\n#endif\n        }\n\n        /// <summary>\n        /// Logs ad revenue data along with additional parameters if provided.\n        /// <param name = \"adRevenueData\" >instance of AFAdRevenueData containing ad revenue information.</param>\n        /// <param name = \"additionalParameters\" >An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters.</param>\n        public void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"logAdRevenue\", adRevenueData.monetizationNetwork, getMediationNetwork(adRevenueData.mediationNetwork), adRevenueData.currencyIso4217Code, adRevenueData.eventRevenue, convertDictionaryToJavaMap(additionalParameters));\n#endif\n        }\n\n        /// <summary>\n        /// Restrict reengagement via deep-link to once per each unique deep-link.\n        /// Otherwise deep re-occurring deep-links will be permitted for non-singleTask Activities and deep-linking via AppsFlyer deep-links.\n        /// The default value is false.\n        /// </summary>\n        /// <param name=\"doConsume\">doConsume boolean.</param>\n        public void setConsumeAFDeepLinks(bool doConsume)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setConsumeAFDeepLinks\", doConsume);\n#endif\n        }\n\n        /// <summary>\n        /// Specify the manufacturer or media source name to which the preinstall is attributed.\n        /// </summary>\n        /// <param name=\"mediaSource\">Manufacturer or media source name for preinstall attribution.</param>\n        /// <param name=\"campaign\">Campaign name for preinstall attribution.</param>\n        /// <param name=\"siteId\">Site ID for preinstall attribution.</param>\n        public void setPreinstallAttribution(string mediaSource, string campaign, string siteId)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setPreinstallAttribution\", mediaSource, campaign, siteId);\n#endif\n        }\n\n        /// <summary>\n        /// Boolean indicator for preinstall by Manufacturer.\n        /// </summary>\n        /// <returns>boolean isPreInstalledApp.</returns>\n        public bool isPreInstalledApp()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<bool>(\"isPreInstalledApp\");\n#else\n            return false;\n#endif\n        }\n\n        /// <summary>\n        /// Get the Facebook attribution ID, if one exists.\n        /// </summary>\n        /// <returns>string Facebook attribution ID.</returns>\n        public string getAttributionId()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getAttributionId\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Get AppsFlyer's unique device ID is created for every new install of an app.\n        /// </summary>\n        /// <returns>AppsFlyer's unique device ID.</returns>\n        public string getAppsFlyerId()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getAppsFlyerId\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// [Deprecated] API for server verification of in-app purchases - please use V2 with AFPurchaseDetailsAndroid instead.\n        /// An af_purchase event with the relevant values will be automatically sent if the validation is successful.\n        /// </summary>\n        /// <param name=\"publicKey\">License Key obtained from the Google Play Console.</param>\n        /// <param name=\"signature\"><code>data.INAPP_DATA_SIGNATURE</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param>\n        /// <param name=\"purchaseData\"><code>data.INAPP_PURCHASE_DATA</code> from <code>onActivityResult(int requestCode, int resultCode, Intent data)</code></param>\n        /// <param name=\"price\">Purchase price, should be derived from <code>skuDetails.getStringArrayList(\"DETAILS_LIST\")</code></param>\n        /// <param name=\"currency\">Purchase currency, should be derived from <code>skuDetails.getStringArrayList(\"DETAILS_LIST\")</code></param>\n        /// <param name=\"additionalParameters\">additionalParameters Freehand parameters to be sent with the purchase (if validated).</param>\n        [System.Obsolete(\"This method is deprecated. Use validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject) instead.\")]\n        public void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n           appsFlyerAndroid.CallStatic(\"validateAndTrackInAppPurchase\", publicKey, signature, purchaseData, price, currency, convertDictionaryToJavaMap(additionalParameters), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// V2 - API for server verification of in-app purchases.\n        /// An af_purchase event with the relevant values will be automatically sent if the validation is successful.\n        /// </summary>\n        /// <param name=\"details\">AFPurchaseDetailsAndroid instance.</param>\n        /// <param name=\"purchaseAdditionalDetails\">purchaseAdditionalDetails Freehand parameters to be sent with the purchase (if validated).</param>\n        public void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n           appsFlyerAndroid.CallStatic(\"validateAndTrackInAppPurchaseV2\", (int)details.purchaseType, details.purchaseToken, details.productId, convertDictionaryToJavaMap(purchaseAdditionalDetails), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// Was the stopSDK(boolean) API set to true.\n        /// </summary>\n        /// <returns>boolean isSDKStopped.</returns>\n        public bool isSDKStopped()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<bool>(\"isTrackingStopped\");\n#else\n            return false;\n#endif\n        }\n\n        /// <summary>\n        /// Set a custom value for the minimum required time between sessions.\n        /// By default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions.\n        /// </summary>\n        /// <param name=\"seconds\">minimum time between 2 separate sessions in seconds.</param>\n        public void setMinTimeBetweenSessions(int seconds)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setMinTimeBetweenSessions\", seconds);\n#endif\n        }\n\n        /// <summary>\n        /// Set a custom host.\n        /// </summary>\n        /// <param name=\"hostPrefixName\">Host prefix.</param>\n        /// <param name=\"hostName\">Host name.</param>\n        public void setHost(string hostPrefixName, string hostName)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setHost\", hostPrefixName, hostName);\n#endif\n        }\n\n        /// <summary>\n        /// Get the host name.\n        /// Default value is  \"appsflyer.com\".\n        /// </summary>\n        /// <returns>Host name.</returns>\n        public string getHostName()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getHostName\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Get the custom host prefix.\n        /// </summary>\n        /// <returns>Host prefix.</returns>\n        public string getHostPrefix()\n        {\n#if !UNITY_EDITOR\n            return appsFlyerAndroid.CallStatic<string>(\"getHostPrefix\");\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Used by advertisers to exclude all networks/integrated partners from getting data.\n        /// </summary>\n        public void setSharingFilterForAllPartners()\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setSharingFilterForAllPartners\");\n#endif\n        }\n\n        /// <summary>\n        /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.\n        /// </summary>\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        public void setSharingFilter(params string[] partners)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setSharingFilter\", (object)partners);\n#endif\n        }\n\n        /// <summary>\n        /// Lets you configure how which partners should the SDK exclude from data-sharing.\n        /// </summary>\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        public static void setSharingFilterForPartners(params string[] partners)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setSharingFilterForPartners\", (object)partners);\n#endif\n        }\n\n        /// <summary>\n        /// Register a Conversion Data Listener.\n        /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level.\n        /// By doing this you can serve users with personalized content or send them to specific activities within the app,\n        /// which can greatly enhance their engagement with your app.\n        /// </summary>\n        public void getConversionData(string objectName)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"getConversionData\", objectName);\n#endif\n        }\n\n        /// <summary>\n        /// Register a validation listener for the validateAndSendInAppPurchase API.\n        /// </summary>\n        public void initInAppPurchaseValidatorListener(MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"initInAppPurchaseValidatorListener\", gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// setCollectOaid\n        /// You must include the appsflyer oaid library for this api to work.\n        /// </summary>\n        /// <param name=\"isCollect\">isCollect oaid - set fasle to opt out</param>\n        public void setCollectOaid(bool isCollect)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"setCollectOaid\", isCollect);\n#endif\n        }\n\n        /// <summary>\n        /// Use the following API to attribute the click and launch the app store's app page.\n        /// </summary>\n        /// <param name=\"promoted_app_id\">promoted App ID</param>\n        /// <param name=\"campaign\">cross promotion campaign</param>\n        /// <param name=\"userParams\">additional user params</param>\n        public void attributeAndOpenStore(string promoted_app_id, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"attributeAndOpenStore\", promoted_app_id, campaign, convertDictionaryToJavaMap(userParams));\n#endif\n        }\n\n        /// <summary>\n        /// To attribute an impression use the following API call.\n        /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.\n        /// </summary>\n        /// <param name=\"appID\">promoted App ID.</param>\n        /// <param name=\"campaign\">cross promotion campaign.</param>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"recordCrossPromoteImpression\", appID, campaign, convertDictionaryToJavaMap(parameters));\n#endif\n        }\n\n        /// <summary>\n        /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click.\n        /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution-\n        /// </summary>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"createOneLinkInviteListener\", convertDictionaryToJavaMap(parameters), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// To measure push notifications as part of a retargeting campaign.\n        /// </summary>\n        public void handlePushNotifications(){\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"handlePushNotifications\");\n#endif\n        }\n\n        /// <summary>\n        /// Use this method if you’re integrating your app with push providers \n        /// that don’t use the default push notification JSON schema the SDK expects.\n        /// See docs for more info.\n        /// </summary>\n        /// <param name=\"paths\">array of nested json path</param>\n        public void addPushNotificationDeepLinkPath(params string[] paths)\n        {\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"addPushNotificationDeepLinkPath\", (object)paths);\n#endif\n        }\n\n        /// <summary>\n        /// subscribe to unified deep link callbacks\n        /// </summary>\n        public void subscribeForDeepLink(string objectName){\n#if !UNITY_EDITOR\n            appsFlyerAndroid.CallStatic(\"subscribeForDeepLink\", objectName);\n#endif\n        }\n\n        /// <summary>\n        /// Disables collection of various Advertising IDs by the SDK. This includes Google Advertising ID (GAID), OAID and Amazon Advertising ID (AAID)\n        /// </summary>\n        /// <param name=\"disable\">disable boolean.</param>\n        public void setDisableAdvertisingIdentifiers(bool disable)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"setDisableAdvertisingIdentifiers\", disable);\n#endif\n        }\n\n        /// <summary>\n        /// Allows sending custom data for partner integration purposes.\n        /// </summary>\n        public void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo)\n        {\n#if !UNITY_EDITOR\n             appsFlyerAndroid.CallStatic(\"setPartnerData\", partnerId, convertDictionaryToJavaMap(partnerInfo));\n#endif\n        }\n\n        /// <summary>\n        /// Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device.\n        /// </summary>\n        public void setDisableNetworkData(bool disable) {\n#if !UNITY_EDITOR\n                appsFlyerAndroid.CallStatic(\"setDisableNetworkData\", disable);\n#endif\n        }\n\n        /// <summary>\n        /// Internal Helper Method.\n        /// </summary>\n        private static AndroidJavaObject getEmailType(EmailCryptType cryptType)\n        {\n            AndroidJavaClass emailsCryptTypeEnum = new AndroidJavaClass(\"com.appsflyer.AppsFlyerProperties$EmailsCryptType\");\n            AndroidJavaObject emailsCryptType;\n\n            switch (cryptType)\n            {\n                case EmailCryptType.EmailCryptTypeSHA256:\n                    emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>(\"SHA256\");\n                    break;\n                default:\n                    emailsCryptType = emailsCryptTypeEnum.GetStatic<AndroidJavaObject>(\"NONE\");\n                    break;\n            }\n\n            return emailsCryptType;\n        }\n\n        /// <summary>\n        /// Internal Helper Method.\n        /// </summary>\n        private static AndroidJavaObject getMediationNetwork(MediationNetwork mediationNetwork)\n        {\n            AndroidJavaClass mediationNetworkEnumClass = new AndroidJavaClass(\"com.appsflyer.MediationNetwork\");\n            AndroidJavaObject mediationNetworkObject;\n\n            switch (mediationNetwork)\n            {\n                case MediationNetwork.IronSource:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"IRONSOURCE\");\n                    break;\n                case MediationNetwork.ApplovinMax:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"APPLOVIN_MAX\");\n                    break;\n                case MediationNetwork.GoogleAdMob:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"GOOGLE_ADMOB\");\n                    break;\n                case MediationNetwork.Fyber:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"FYBER\");\n                    break;\n                case MediationNetwork.Appodeal:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"APPODEAL\");\n                    break;\n                case MediationNetwork.Admost:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"ADMOST\");\n                    break;\n                case MediationNetwork.Topon:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"TOPON\");\n                    break;\n                case MediationNetwork.Tradplus:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"TRADPLUS\");\n                    break;\n                case MediationNetwork.Yandex:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"YANDEX\");\n                    break;\n                case MediationNetwork.ChartBoost:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"CHARTBOOST\");\n                    break;\n                case MediationNetwork.Unity:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"UNITY\");\n                    break;\n                case MediationNetwork.ToponPte:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"TOPON_PTE\");\n                    break;\n                case MediationNetwork.Custom:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"CUSTOM_MEDIATION\");\n                    break;\n                case MediationNetwork.DirectMonetization:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"DIRECT_MONETIZATION_NETWORK\");\n                    break;\n                default:\n                    mediationNetworkObject = mediationNetworkEnumClass.GetStatic<AndroidJavaObject>(\"NONE\");\n                    break;\n        }\n        return mediationNetworkObject;\n        }\n\n        /// <summary>\n        /// Internal Helper Method.\n        /// </summary>\n        private static AndroidJavaObject convertDictionaryToJavaMap(Dictionary<string, string> dictionary)\n        {\n            AndroidJavaObject map = new AndroidJavaObject(\"java.util.HashMap\");\n            IntPtr putMethod = AndroidJNIHelper.GetMethodID(map.GetRawClass(), \"put\", \"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;\");\n            jvalue[] val;\n            if (dictionary != null)\n            {\n                foreach (var entry in dictionary)\n                {\n                    val = AndroidJNIHelper.CreateJNIArgArray(new object[] { entry.Key, entry.Value });\n                    AndroidJNI.CallObjectMethod(map.GetRawObject(), putMethod,val);\n                    AndroidJNI.DeleteLocalRef(val[0].l);\n                    AndroidJNI.DeleteLocalRef(val[1].l);\n                }\n            }\n            \n            return map;\n        }\n    }\n#endif\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerAndroid.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 172d18dd98e7e4ed3b30110568b0fae4\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerConsent.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    /// <summary>\n    // Data class representing a user's consent for data processing in accordance with GDPR and DMA\n    // (Digital Markets Act) compliance, specifically regarding advertising preferences.\n  \n    // This class should be used to notify and record the user's applicability\n    // under GDPR, their general consent to data usage, and their consent to personalized\n    // advertisements based on user data.\n    \n    /// ## Properties:\n    /// - `isUserSubjectToGDPR` (optional) - Indicates whether GDPR regulations apply to the user. \n    ///   This may also serve as a general compliance flag for other regional regulations.\n    /// - `hasConsentForDataUsage` (optional) - Indicates whether the user consents to the processing \n    ///   of their data for advertising purposes.\n    /// - `hasConsentForAdsPersonalization` (optional) - Indicates whether the user consents to the \n    ///   use of their data for personalized advertising.\n    /// - `hasConsentForAdStorage` (optional) - Indicates whether the user consents to ad-related storage access.\n    ///\n    /// **Usage Example:**\n    /// ```csharp\n    /// var consent = new AppsFlyerConsent(\n    ///     isUserSubjectToGDPR: true, \n    ///     hasConsentForDataUsage: true, \n    ///     hasConsentForAdsPersonalization: false, \n    ///     hasConsentForAdStorage: true\n    /// );\n    /// **Deprecated APIs:**\n    /// - `ForGDPRUser(...)` and `ForNonGDPRUser(...)` should no longer be used.\n    /// - Use `new AppsFlyerConsent(...)` instead with relevant consent fields.\n    ///\n    /// </summary>\n    public class AppsFlyerConsent\n    {\n        public bool? isUserSubjectToGDPR { get; private set; }\n        public bool? hasConsentForDataUsage { get; private set; }\n        public bool? hasConsentForAdsPersonalization { get; private set; }\n        public bool? hasConsentForAdStorage { get; private set; }\n\n        public AppsFlyerConsent( bool? isUserSubjectToGDPR = null, bool? hasConsentForDataUsage = null, bool? hasConsentForAdsPersonalization = null, bool? hasConsentForAdStorage = null)\n        {\n            this.isUserSubjectToGDPR = isUserSubjectToGDPR;\n            this.hasConsentForDataUsage = hasConsentForDataUsage;\n            this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization;\n            this.hasConsentForAdStorage = hasConsentForAdStorage;\n        }\n\n        [Obsolete(\"Use the new constructor with optional booleans instead.\")]\n        private AppsFlyerConsent(bool isGDPR, bool hasForDataUsage, bool hasForAdsPersonalization)\n        {\n            isUserSubjectToGDPR = isGDPR;\n            hasConsentForDataUsage = hasForDataUsage;\n            hasConsentForAdsPersonalization = hasForAdsPersonalization;\n        }\n\n        [Obsolete(\"Use new AppsFlyerConsent(...) instead.\")]\n        public static AppsFlyerConsent ForGDPRUser(bool hasConsentForDataUsage, bool hasConsentForAdsPersonalization)\n        {\n            return new AppsFlyerConsent(true, hasConsentForDataUsage, hasConsentForAdsPersonalization);\n        }\n\n        [Obsolete(\"Use new AppsFlyerConsent(...) instead.\")]\n        public static AppsFlyerConsent ForNonGDPRUser()\n        {\n            return new AppsFlyerConsent(false);\n        }\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerConsent.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a97c986fe4ee0461badf7042e08db3f3\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerEventArgs.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AppsFlyerSDK\n{\n    \n    /// <summary>\n    /// Event args for AppsFlyer requests.\n    /// Used for sessions and in-app events.\n    /// Used to handle post request logic.\n    /// \n    /// Examples:\n    /// statusCode / errorDescription\n    /// \n    /// 200 - null\n    /// \n    /// 10 - \"Event timeout. Check 'minTimeBetweenSessions' param\"\n    /// 11 - \"Skipping event because 'isStopTracking' enabled\"\n    /// 40 - Network error: Error description comes from Android\n    /// 41 - \"No dev key\"\n    /// 50 - \"Status code failure\" + actual response code from the server\n    /// \n    /// </summary>\n    public class AppsFlyerRequestEventArgs : EventArgs\n    {\n        public AppsFlyerRequestEventArgs(int code, string description)\n        {\n            statusCode = code;\n            errorDescription = description;\n        }\n\n        public int statusCode { get; }\n        public string errorDescription { get; }\n    }\n\n    /// <summary>\n    /// Event args for OnDeepLinkReceived.\n    /// Used to handle deep linking results.\n    /// </summary>\n    public class DeepLinkEventsArgs : EventArgs\n    {\n        \n        /// <summary>\n        /// DeepLink dictionary to get additional parameters\n        /// </summary>\n        public Dictionary<string, object> deepLink;\n        \n        /// <summary>\n        /// DeepLink status: FOUND, NOT_FOUND, ERROR\n        /// </summary>\n        public DeepLinkStatus status { get; }\n        \n        /// <summary>\n        /// DeepLink error: TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED\n        /// </summary>\n        public DeepLinkError error { get; }\n\n        public string getMatchType()\n        {\n            return getDeepLinkParameter(\"match_type\");\n        }\n\n        public string getDeepLinkValue()\n        {\n            return getDeepLinkParameter(\"deep_link_value\");\n        }\n\n        public string getClickHttpReferrer()\n        {\n            return getDeepLinkParameter(\"click_http_referrer\");\n        }\n\n        public string getMediaSource()\n        {\n            return getDeepLinkParameter(\"media_source\");\n        }\n\n        public string getCampaign()\n        {\n            return getDeepLinkParameter(\"campaign\");\n        }\n\n        public string getCampaignId()\n        {\n            return getDeepLinkParameter(\"campaign_id\");\n        }\n\n        public string getAfSub1()\n        {\n            return getDeepLinkParameter(\"af_sub1\");\n        }\n\n        public string getAfSub2()\n        {\n            return getDeepLinkParameter(\"af_sub2\");\n        }\n\n        public string getAfSub3()\n        { \n            return getDeepLinkParameter(\"af_sub3\");\n        }\n\n        public string getAfSub4()\n        {\n            return getDeepLinkParameter(\"af_sub4\");\n        }\n\n        public string getAfSub5()\n        {\n            return getDeepLinkParameter(\"af_sub5\");\n        }\n\n        public bool isDeferred()\n        {\n            if (deepLink != null && deepLink.ContainsKey(\"is_deferred\"))\n            {\n                try\n                {\n                    return (bool)deepLink[\"is_deferred\"];\n                }\n                catch (Exception e)\n                {\n                    AppsFlyer.AFLog(\"DeepLinkEventsArgs.isDeferred\", String.Format(\"{0} Exception caught.\", e));\n                }\n            }\n            return false;\n        }\n\n        public Dictionary<string, object> getDeepLinkDictionary()\n        {\n            return deepLink;\n        }\n        \n        public DeepLinkEventsArgs(string str)\n        {\n            try\n            {\n                Dictionary<string, object> dictionary = AppsFlyer.CallbackStringToDictionary(str);\n\n                string status = \"\";\n                string error = \"\";\n\n                \n                if (dictionary.ContainsKey(\"status\") && dictionary[\"status\"] != null)\n                {\n                    status = dictionary[\"status\"].ToString();\n                }\n                \n                if (dictionary.ContainsKey(\"error\") && dictionary[\"error\"] != null)\n                {\n                    error = dictionary[\"error\"].ToString();\n                }\n                \n                if (dictionary.ContainsKey(\"deepLink\") && dictionary[\"deepLink\"] != null)\n                {\n                    this.deepLink = AppsFlyer.CallbackStringToDictionary(dictionary[\"deepLink\"].ToString());\n                }\n                if (dictionary.ContainsKey(\"is_deferred\"))\n                {\n                    this.deepLink[\"is_deferred\"] = dictionary[\"is_deferred\"];\n                }\n\n                switch (status)\n                {\n                    case \"FOUND\":\n                        this.status = DeepLinkStatus.FOUND;\n                        break;\n                    case \"NOT_FOUND\":\n                        this.status = DeepLinkStatus.NOT_FOUND;\n                        break;\n                    default:\n                        this.status = DeepLinkStatus.ERROR;\n                        break;\n                }\n                \n                switch (error)\n                {\n                    case \"TIMEOUT\":\n                        this.error = DeepLinkError.TIMEOUT;\n                        break;\n                    case \"NETWORK\":\n                        this.error = DeepLinkError.NETWORK;\n                        break;\n                    case \"HTTP_STATUS_CODE\":\n                        this.error = DeepLinkError.HTTP_STATUS_CODE;\n                        break;\n                    default:\n                        this.error = DeepLinkError.UNEXPECTED;\n                        break;\n                }\n                \n            }\n            catch (Exception e)\n            {\n                AppsFlyer.AFLog(\"DeepLinkEventsArgs.parseDeepLink\", String.Format(\"{0} Exception caught.\", e));\n            }\n        }\n        \n        private string getDeepLinkParameter(string name)\n        {\n            if (deepLink != null && deepLink.ContainsKey(name) && deepLink[name] != null)\n            {\n                return deepLink[name].ToString();\n            }\n            \n            return null;\n        }\n        \n    }\n\n    public enum DeepLinkStatus {\n        FOUND, NOT_FOUND, ERROR\n    }\n\n    public enum DeepLinkError {\n        TIMEOUT, NETWORK, HTTP_STATUS_CODE, UNEXPECTED\n    }\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerEventArgs.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a0fc241ad5a9b43a7b461a6147dbc74c\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerObject.prefab",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!1 &7315102894599890749\nGameObject:\n  m_ObjectHideFlags: 0\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  serializedVersion: 6\n  m_Component:\n  - component: {fileID: 6207133488976360133}\n  - component: {fileID: 4405976200006927252}\n  m_Layer: 0\n  m_Name: AppsFlyerObject\n  m_TagString: Untagged\n  m_Icon: {fileID: 0}\n  m_NavMeshLayer: 0\n  m_StaticEditorFlags: 0\n  m_IsActive: 1\n--- !u!4 &6207133488976360133\nTransform:\n  m_ObjectHideFlags: 0\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 7315102894599890749}\n  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}\n  m_LocalPosition: {x: 0, y: 0, z: 0}\n  m_LocalScale: {x: 1, y: 1, z: 1}\n  m_Children: []\n  m_Father: {fileID: 0}\n  m_RootOrder: 0\n  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}\n--- !u!114 &4405976200006927252\nMonoBehaviour:\n  m_ObjectHideFlags: 0\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 7315102894599890749}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 11500000, guid: 2a2ec6ba1ee8b48749524f015ed572a6, type: 3}\n  m_Name: \n  m_EditorClassIdentifier: \n  devKey: \n  appID: \n  isDebug: 0\n  getConversionData: 0\n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerObject.prefab.meta",
    "content": "fileFormatVersion: 2\nguid: 0bfe3b149145747cc92dc53bb4df4e9b\nPrefabImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerObjectScript.cs",
    "content": "using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\nusing AppsFlyerSDK;\n\n// This class is intended to be used the the AppsFlyerObject.prefab\n\npublic class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData\n{\n\n    // These fields are set from the editor so do not modify!\n    //******************************//\n    public string devKey;\n    public string appID;\n    public string UWPAppID;\n    public string macOSAppID;\n    public bool isDebug;\n    public bool getConversionData;\n    //******************************//\n\n\n    void Start()\n    {\n        // These fields are set from the editor so do not modify!\n        //******************************//\n        AppsFlyer.setIsDebug(isDebug);\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n        AppsFlyer.initSDK(devKey, UWPAppID, getConversionData ? this : null);\n#elif UNITY_STANDALONE_OSX && !UNITY_EDITOR\n    AppsFlyer.initSDK(devKey, macOSAppID, getConversionData ? this : null);\n#else\n        AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);\n#endif\n        //******************************/\n \n        AppsFlyer.startSDK();\n    }\n\n\n    void Update()\n    {\n\n    }\n\n    // Mark AppsFlyer CallBacks\n    public void onConversionDataSuccess(string conversionData)\n    {\n        AppsFlyer.AFLog(\"didReceiveConversionData\", conversionData);\n        Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);\n        // add deferred deeplink logic here\n    }\n\n    public void onConversionDataFail(string error)\n    {\n        AppsFlyer.AFLog(\"didReceiveConversionDataWithError\", error);\n    }\n\n    public void onAppOpenAttribution(string attributionData)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttribution\", attributionData);\n        Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);\n        // add direct deeplink logic here\n    }\n\n    public void onAppOpenAttributionFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttributionFailure\", error);\n    }\n\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerObjectScript.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 2a2ec6ba1ee8b48749524f015ed572a6\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerPurchaseConnector.cs",
    "content": "using System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing UnityEngine;\nusing System;\n\nnamespace AppsFlyerSDK\n{\n\n        public interface IAppsFlyerPurchaseRevenueDataSource\n        {\n                Dictionary<string, object> PurchaseRevenueAdditionalParametersForProducts(HashSet<object> products, HashSet<object> transactions);\n        }\n\n        public interface IAppsFlyerPurchaseRevenueDataSourceStoreKit2\n        {\n                Dictionary<string, object> PurchaseRevenueAdditionalParametersStoreKit2ForProducts(HashSet<object> products, HashSet<object> transactions);\n        }\n\n        public class AppsFlyerPurchaseRevenueBridge : MonoBehaviour\n        {\n                        #if UNITY_IOS && !UNITY_EDITOR\n[DllImport(\"__Internal\")]\nprivate static extern void RegisterUnityPurchaseRevenueParamsCallback(Func<string, string, string> callback);\n\n[DllImport(\"__Internal\")]\nprivate static extern void RegisterUnityPurchaseRevenueParamsCallbackSK2(Func<string, string, string> callback);\n#endif\n                \n                private static IAppsFlyerPurchaseRevenueDataSource _dataSource;\n                private static IAppsFlyerPurchaseRevenueDataSourceStoreKit2 _dataSourceSK2;\n\n                public static void RegisterDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource)\n                {\n                        _dataSource = dataSource;\n        #if UNITY_IOS && !UNITY_EDITOR\n                        RegisterUnityPurchaseRevenueParamsCallback(GetAdditionalParameters);\n        #elif UNITY_ANDROID && !UNITY_EDITOR\n                        using (AndroidJavaClass jc = new AndroidJavaClass(\"com.appsflyer.unity.PurchaseRevenueBridge\"))\n                        {\n                                jc.CallStatic(\"setUnityBridge\", new UnityPurchaseRevenueBridgeProxy());\n                        }\n        #endif\n                }\n\n                public static void RegisterDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSource)\n                {\n                #if UNITY_IOS && !UNITY_EDITOR\n                        _dataSourceSK2 = dataSource;\n                        RegisterUnityPurchaseRevenueParamsCallbackSK2(GetAdditionalParametersSK2);\n                #endif\n                }\n\n                public static Dictionary<string, object> GetAdditionalParametersForAndroid(HashSet<object> products, HashSet<object> transactions)\n                {\n                        return _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions)\n                        ?? new Dictionary<string, object>();\n                }\n\n        #if UNITY_IOS && !UNITY_EDITOR\n                [AOT.MonoPInvokeCallback(typeof(Func<string, string, string>))]\n                public static string GetAdditionalParameters(string productsJson, string transactionsJson)\n                {\n                        try\n                        {\n                                HashSet<object> products = new HashSet<object>();\n                                HashSet<object> transactions = new HashSet<object>();\n\n                                if (!string.IsNullOrEmpty(productsJson))\n                                {\n                                var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary<string, object>;\n                                if (dict != null)\n                                {\n                                        if (dict.TryGetValue(\"products\", out var productsObj) && productsObj is List<object> productList)\n                                        products = new HashSet<object>(productList);\n\n                                        if (dict.TryGetValue(\"transactions\", out var transactionsObj) && transactionsObj is List<object> transactionList)\n                                        transactions = new HashSet<object>(transactionList);\n                                }\n                                }\n\n                                var parameters = _dataSource?.PurchaseRevenueAdditionalParametersForProducts(products, transactions)\n                                                ?? new Dictionary<string, object>();\n                                return AFMiniJSON.Json.Serialize(parameters);\n                        }\n                        catch (Exception e)\n                        {\n                                Debug.LogError($\"[AppsFlyer] Exception in GetAdditionalParameters: {e}\");\n                                return \"{}\";\n                        }\n                }\n        #endif\n\n        #if UNITY_IOS && !UNITY_EDITOR\n                [AOT.MonoPInvokeCallback(typeof(Func<string, string, string>))]\n                public static string GetAdditionalParametersSK2(string productsJson, string transactionsJson)\n                {\n                        try\n                        {\n                                HashSet<object> products = new HashSet<object>();\n                                HashSet<object> transactions = new HashSet<object>();\n\n                                if (!string.IsNullOrEmpty(productsJson))\n                                {\n                                        var dict = AFMiniJSON.Json.Deserialize(productsJson) as Dictionary<string, object>;\n                                        if (dict != null && dict.TryGetValue(\"products\", out var productsObj) && productsObj is List<object> productList)\n                                                products = new HashSet<object>(productList);\n                                }\n                                if (!string.IsNullOrEmpty(transactionsJson))\n                                {\n                                        var dict = AFMiniJSON.Json.Deserialize(transactionsJson) as Dictionary<string, object>;\n                                        if (dict != null && dict.TryGetValue(\"transactions\", out var transactionsObj) && transactionsObj is List<object> transactionList)\n                                                transactions = new HashSet<object>(transactionList);\n                                }\n\n                                var parameters = _dataSourceSK2?.PurchaseRevenueAdditionalParametersStoreKit2ForProducts(products, transactions)\n                                                ?? new Dictionary<string, object>();\n                                return AFMiniJSON.Json.Serialize(parameters);\n                        }\n                        catch (Exception e)\n                        {\n                                Debug.LogError($\"[AppsFlyer] Exception in GetAdditionalParametersSK2: {e}\");\n                                return \"{}\";\n                        }\n                }\n        #endif\n        }\n\n        public class UnityPurchaseRevenueBridgeProxy : AndroidJavaProxy\n        {\n                public UnityPurchaseRevenueBridgeProxy() : base(\"com.appsflyer.unity.PurchaseRevenueBridge$UnityPurchaseRevenueBridge\") { }\n\n                public string getAdditionalParameters(string productsJson, string transactionsJson)\n                {\n                        try\n                        {\n                                // Create empty sets if JSON is null or empty\n                                HashSet<object> products = new HashSet<object>();\n                                HashSet<object> transactions = new HashSet<object>();\n\n                                // Only try to parse if we have valid JSON\n                                if (!string.IsNullOrEmpty(productsJson))\n                                {\n                                        try\n                                        {\n                                                // First try to parse as a simple array\n                                                var parsedProducts = AFMiniJSON.Json.Deserialize(productsJson);\n                                                if (parsedProducts is List<object> productList)\n                                                {\n                                                        products = new HashSet<object>(productList);\n                                                }\n                                                else if (parsedProducts is Dictionary<string, object> dict)\n                                                {\n                                                        if (dict.ContainsKey(\"events\") && dict[\"events\"] is List<object> eventsList)\n                                                        {\n                                                                products = new HashSet<object>(eventsList);\n                                                        }\n                                                        else\n                                                        {\n                                                                // If it's a dictionary but doesn't have events, add the whole dict\n                                                                products.Add(dict);\n                                                        }\n                                                }\n                                        }\n                                        catch (Exception e)\n                                        {\n                                                Debug.LogError($\"Error parsing products JSON: {e.Message}\\nJSON: {productsJson}\");\n                                        }\n                                }\n\n                                if (!string.IsNullOrEmpty(transactionsJson))\n                                {\n                                        try\n                                        {\n                                                // First try to parse as a simple array\n                                                var parsedTransactions = AFMiniJSON.Json.Deserialize(transactionsJson);\n                                                if (parsedTransactions is List<object> transactionList)\n                                                {\n                                                        transactions = new HashSet<object>(transactionList);\n                                                }\n                                                else if (parsedTransactions is Dictionary<string, object> dict)\n                                                {\n                                                        if (dict.ContainsKey(\"events\") && dict[\"events\"] is List<object> eventsList)\n                                                        {\n                                                                transactions = new HashSet<object>(eventsList);\n                                                        }\n                                                        else\n                                                        {\n                                                                // If it's a dictionary but doesn't have events, add the whole dict\n                                                                transactions.Add(dict);\n                                                        }\n                                                }\n                                        }\n                                        catch (Exception e)\n                                        {\n                                                Debug.LogError($\"Error parsing transactions JSON: {e.Message}\\nJSON: {transactionsJson}\");\n                                        }\n                                }\n\n                                var parameters = AppsFlyerPurchaseRevenueBridge.GetAdditionalParametersForAndroid(products, transactions);\n                                return AFMiniJSON.Json.Serialize(parameters);\n                        }\n                        catch (Exception e)\n                        {\n                                Debug.LogError($\"Error in getAdditionalParameters: {e.Message}\\nProducts JSON: {productsJson}\\nTransactions JSON: {transactionsJson}\");\n                                return \"{}\";\n                        }\n                }\n        }\n\n    \n        public class AppsFlyerPurchaseConnector : MonoBehaviour {\n\n        private static AppsFlyerPurchaseConnector instance;\n        private Dictionary<string, object> pendingParameters;\n        private Action<Dictionary<string, object>> pendingCallback;\n\n        public static AppsFlyerPurchaseConnector Instance\n        {\n            get\n            {\n                if (instance == null)\n                {\n                    GameObject go = new GameObject(\"AppsFlyerPurchaseConnector\");\n                    instance = go.AddComponent<AppsFlyerPurchaseConnector>();\n                    DontDestroyOnLoad(go);\n                }\n                return instance;\n            }\n        }\n\n        private void Awake()\n        {\n            if (instance == null)\n            {\n                instance = this;\n                DontDestroyOnLoad(gameObject);\n            }\n            else\n            {\n                Destroy(gameObject);\n            }\n        }\n\n#if UNITY_ANDROID && !UNITY_EDITOR\n        private static AndroidJavaClass appsFlyerAndroidConnector = new AndroidJavaClass(\"com.appsflyer.unity.AppsFlyerAndroidWrapper\");\n#endif\n\n        public static void init(MonoBehaviour unityObject, Store s) {\n#if UNITY_IOS && !UNITY_EDITOR\n                _initPurchaseConnector(unityObject.name);\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                int store = mapStoreToInt(s);\n                appsFlyerAndroidConnector.CallStatic(\"initPurchaseConnector\", unityObject ? unityObject.name : null, store);\n#endif\n        }\n\n        public static void build() {\n#if UNITY_IOS && !UNITY_EDITOR\n        //not for iOS\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                appsFlyerAndroidConnector.CallStatic(\"build\");\n\n#else\n#endif\n        }\n\n        public static void startObservingTransactions() {\n#if UNITY_IOS && !UNITY_EDITOR\n                _startObservingTransactions();\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                appsFlyerAndroidConnector.CallStatic(\"startObservingTransactions\");\n#else \n#endif\n        }\n\n        public static void stopObservingTransactions() {\n#if UNITY_IOS && !UNITY_EDITOR\n                _stopObservingTransactions();\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                appsFlyerAndroidConnector.CallStatic(\"stopObservingTransactions\");\n#else\n#endif\n        }\n\n        public static void setIsSandbox(bool isSandbox) {\n#if UNITY_IOS && !UNITY_EDITOR\n                _setIsSandbox(isSandbox);\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                appsFlyerAndroidConnector.CallStatic(\"setIsSandbox\", isSandbox);\n#else\n#endif\n        }\n\n        public static void setPurchaseRevenueValidationListeners(bool enableCallbacks) {\n#if UNITY_IOS && !UNITY_EDITOR\n                _setPurchaseRevenueDelegate();\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                appsFlyerAndroidConnector.CallStatic(\"setPurchaseRevenueValidationListeners\", enableCallbacks);\n#else\n#endif\n        }\n\n        public static void setAutoLogPurchaseRevenue(params AppsFlyerAutoLogPurchaseRevenueOptions[] autoLogPurchaseRevenueOptions) {\n#if UNITY_IOS && !UNITY_EDITOR\n                int option = 0;\n                foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) {\n                        option = option | (int)op;\n                }\n                _setAutoLogPurchaseRevenue(option);\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                if (autoLogPurchaseRevenueOptions.Length == 0) {\n                        return;\n                }\n                foreach (AppsFlyerAutoLogPurchaseRevenueOptions op in autoLogPurchaseRevenueOptions) {\n                        switch(op) {\n                                case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsDisabled:\n                                        break;\n                                case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions:\n                                        appsFlyerAndroidConnector.CallStatic(\"setAutoLogSubscriptions\", true);\n                                        break;\n                                case AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases:\n                                        appsFlyerAndroidConnector.CallStatic(\"setAutoLogInApps\", true);\n                                        break;\n                                default:\n                                        break;\n                        }\n                }\n#else\n#endif\n        }\n\n        public static void setPurchaseRevenueDataSource(IAppsFlyerPurchaseRevenueDataSource dataSource)\n        {\n#if UNITY_IOS && !UNITY_EDITOR\n\n                if (dataSource != null)\n                {\n                        _setPurchaseRevenueDataSource(dataSource.GetType().Name);\n                        AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource);\n                }\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                if (dataSource != null)\n                {\n                        AppsFlyerPurchaseRevenueBridge.RegisterDataSource(dataSource);\n                }\n#endif\n        }\n\n\n        public static void setPurchaseRevenueDataSourceStoreKit2(IAppsFlyerPurchaseRevenueDataSourceStoreKit2 dataSourceSK2)\n        {\n#if UNITY_IOS && !UNITY_EDITOR\n                if (dataSourceSK2 != null)\n                {\n                        AppsFlyerPurchaseRevenueBridge.RegisterDataSourceStoreKit2(dataSourceSK2);\n                        _setPurchaseRevenueDataSource(\"AppsFlyerObjectScript_StoreKit2\");\n                }\n#endif\n        }\n\n\n        private static int mapStoreToInt(Store s) {\n                switch(s) {\n                        case(Store.GOOGLE):\n                                return 0;\n                        default:\n                                return -1;\n                }\n        }\n\n        public static void setStoreKitVersion(StoreKitVersion storeKitVersion) {\n#if UNITY_IOS && !UNITY_EDITOR\n                _setStoreKitVersion((int)storeKitVersion);\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                // Android doesn't use StoreKit\n#else\n#endif\n        }\n\n        public static void logConsumableTransaction(string transactionJson) {\n#if UNITY_IOS && !UNITY_EDITOR\n                _logConsumableTransaction(transactionJson);\n#elif UNITY_ANDROID && !UNITY_EDITOR\n                // Android doesn't use StoreKit\n#else\n#endif\n        }\n\n#if UNITY_IOS && !UNITY_EDITOR\n\n    [DllImport(\"__Internal\")]\n    private static extern void _startObservingTransactions();\n    [DllImport(\"__Internal\")]\n    private static extern void _stopObservingTransactions();\n    [DllImport(\"__Internal\")]\n    private static extern void _setIsSandbox(bool isSandbox);\n    [DllImport(\"__Internal\")]\n    private static extern void _setPurchaseRevenueDelegate();\n    [DllImport(\"__Internal\")]\n    private static extern void _setPurchaseRevenueDataSource(string dataSourceName);\n    [DllImport(\"__Internal\")]\n    private static extern void _setAutoLogPurchaseRevenue(int option);\n    [DllImport(\"__Internal\")]\n    private static extern void _initPurchaseConnector(string objectName);\n    [DllImport(\"__Internal\")]\n    private static extern void _setStoreKitVersion(int storeKitVersion);\n    [DllImport(\"__Internal\")]\n    private static extern void _logConsumableTransaction(string transactionJson);\n\n#endif\n        }\n    public enum Store {\n    GOOGLE = 0\n    }\n    public enum AppsFlyerAutoLogPurchaseRevenueOptions\n    {\n        AppsFlyerAutoLogPurchaseRevenueOptionsDisabled = 0,\n        AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions = 1 << 0,\n        AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases = 1 << 1\n    }\n\n    public enum StoreKitVersion {\n        SK1 = 0,\n        SK2 = 1\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyerPurchaseConnector.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 0636ea07d370d437183f3762280c08ce\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyeriOS.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing UnityEngine;\nusing System.Reflection;\n\n\n\nnamespace AppsFlyerSDK\n{\n\n#if UNITY_IOS || UNITY_STANDALONE_OSX\n\n    public class AppsFlyeriOS: IAppsFlyerIOSBridge\n    {\n        public bool isInit { get; set;  }\n\n        public AppsFlyeriOS() { }\n\n        public AppsFlyeriOS(string devKey, string appID, MonoBehaviour gameObject)\n        {\n            setAppsFlyerDevKey(devKey);\n            setAppleAppID(appID);\n            if (gameObject != null)\n            {\n#if UNITY_IOS\n                getConversionData(gameObject.name);\n#elif UNITY_STANDALONE_OSX\n                getConversionData(gameObject.GetType().ToString());\n#endif\n            }\n        }\n\n\n\n        /// <summary>\n        /// Start Session.\n        /// This will record a session and then record all background forground sessions during the lifecycle of the app.\n        /// </summary>\npublic void startSDK(bool shouldCallback, string CallBackObjectName)\n        {\n#if UNITY_STANDALONE_OSX && !UNITY_EDITOR\n                _startSDK(shouldCallback, CallBackObjectName, getCallback);\n#elif UNITY_IOS && !UNITY_EDITOR\n                _startSDK(shouldCallback, CallBackObjectName); \n#endif\n        }\n\n        /// <summary>\n        /// Send an In-App Event.\n        /// In-App Events provide insight on what is happening in your app.\n        /// </summary>\n        /// <param name=\"eventName\">Name of event.</param>\n        /// <param name=\"eventValues\">Contains dictionary of values for handling by backend.</param>\n        public  void sendEvent(string eventName, Dictionary<string, string> eventValues)\n        {\n            sendEvent(eventName, eventValues, false, AppsFlyer.CallBackObjectName);\n        }\n        \n        public void sendEvent(string eventName, Dictionary<string, string> eventValues, bool shouldCallback, string callBackObjectName)\n        {\n#if !UNITY_EDITOR\n           _afSendEvent(eventName, AFMiniJSON.Json.Serialize(eventValues), shouldCallback, callBackObjectName);\n#endif\n        }\n\n        /// <summary>\n        /// Get the conversion data.\n        /// Allows the developer to access the user attribution data in real-time for every new install, directly from the SDK level.\n        /// By doing this you can serve users with personalized content or send them to specific activities within the app,\n        /// which can greatly enhance their engagement with your app.\n        /// </summary>\n        public void getConversionData(string objectName)\n        {\n#if !UNITY_EDITOR\n            _getConversionData(objectName);\n#endif\n        }\n\n        /// <summary>\n        /// In case you use your own user ID in your app, you can set this property to that ID.\n        /// Enables you to cross-reference your own unique ID with AppsFlyer’s unique ID and the other devices’ IDs.\n        /// </summary>\n        /// <param name=\"customerUserID\">Customer ID for client.</param>\n        public void setCustomerUserId(string customerUserID)\n        {\n#if !UNITY_EDITOR\n            _setCustomerUserID(customerUserID);\n#endif\n        }\n\n        /// <summary>\n        ///  In case you use custom data and you want to receive it in the raw reports.\n        /// see [Setting additional custom data] (https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS#setting-additional-custom-data) for more information.\n        /// </summary>\n        /// <param name=\"customData\">additional data Dictionary.</param>\n        public void setAdditionalData(Dictionary<string, string> customData)\n        {\n#if !UNITY_EDITOR\n           _setAdditionalData(AFMiniJSON.Json.Serialize(customData));\n#endif\n        }\n\n        /// <summary>\n        ///  Use this method to set your AppsFlyer's dev key.\n        /// </summary>\n        /// <param name=\"appsFlyerDevKey\">AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.</param>\n        public void setAppsFlyerDevKey(string appsFlyerDevKey)\n        {\n#if !UNITY_EDITOR\n           _setAppsFlyerDevKey(appsFlyerDevKey);\n#endif\n        }\n\n        /// <summary>\n        /// Use this method to set your app's Apple ID(taken from the app's page on iTunes Connect).\n        /// </summary>\n        /// <param name=\"appleAppID\">your app's Apple ID.</param>\n        public void setAppleAppID(string appleAppID)\n        {\n#if !UNITY_EDITOR\n           _setAppleAppID(appleAppID);\n#endif\n        }\n\n        /// <summary>\n        /// Setting user local currency code for in-app purchases.\n        /// The currency code should be a 3 character ISO 4217 code. (default is USD).\n        /// You can set the currency code for all events by calling the following method.\n        /// </summary>\n        /// <param name=\"currencyCode\">3 character ISO 4217 code.</param>\n        public void setCurrencyCode(string currencyCode)\n        {\n#if !UNITY_EDITOR\n           _setCurrencyCode(currencyCode);\n#endif\n        }\n\n        /// <summary>\n        ///  AppsFlyer SDK collect Apple's `advertisingIdentifier` if the `AdSupport.framework` included in the SDK.\n        /// You can disable this behavior by setting the following property to true.\n        /// </summary>\n        /// <param name=\"disableCollectAppleAdSupport\">boolean to disableCollectAppleAdSupport</param>\n        public void setDisableCollectAppleAdSupport(bool disableCollectAppleAdSupport)\n        {\n#if !UNITY_EDITOR\n           _setDisableCollectAppleAdSupport(disableCollectAppleAdSupport);\n#endif\n        }\n\n        /// <summary>\n        /// Enables Debug logs for the AppsFlyer SDK.\n        /// Should only be set to true in development / debug.\n        /// The default value is false.\n        /// </summary>\n        /// <param name=\"isDebug\">shouldEnable boolean..</param>\n        public void setIsDebug(bool isDebug)\n        {\n#if !UNITY_EDITOR\n           _setIsDebug(isDebug);\n#endif\n        }\n\n        /// <summary>\n        /// Set this flag to true, to collect the current device name(e.g. \"My iPhone\"). Default value is false.\n        /// </summary>\n        /// <param name=\"shouldCollectDeviceName\">boolean shouldCollectDeviceName.</param>\n         [System.Obsolete(\"This is deprecated\")]\n        public void setShouldCollectDeviceName(bool shouldCollectDeviceName)\n        {\n#if !UNITY_EDITOR\n            _setShouldCollectDeviceName(shouldCollectDeviceName);\n#endif\n        }\n\n        /// <summary>\n        /// Set the OneLink ID that should be used for User-Invites.\n        /// The link that is generated for the user invite will use this OneLink as the base link.\n        /// </summary>\n        /// <param name=\"appInviteOneLinkID\">OneLink ID obtained from the AppsFlyer Dashboard.</param>\n        public void setAppInviteOneLinkID(string appInviteOneLinkID)\n        {\n#if !UNITY_EDITOR\n            _setAppInviteOneLinkID(appInviteOneLinkID);\n#endif\n        }\n\n        /// <summary>\n        /// Set the deepLink timeout value that should be used for DDL.\n        /// </summary>\n        /// <param name=\"deepLinkTimeout\">deepLink timeout in milliseconds.</param>\n        public void setDeepLinkTimeout(long deepLinkTimeout)\n        {\n#if !UNITY_EDITOR\n            _setDeepLinkTimeout(deepLinkTimeout);\n#endif\n         }\n\n        /// <summary>\n        /// Calling enableTCFDataCollection(true) will enable collecting and sending any TCF related data.\n        /// Calling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it.\n        /// </summary>\n        /// <param name = \"shouldCollectTcfData\" >should start TCF Data collection boolean.</param>\n        public void enableTCFDataCollection(bool shouldCollectTcfData)\n        {\n#if !UNITY_EDITOR\n            _enableTCFDataCollection(shouldCollectTcfData);\n#endif\n         }\n\n        /// <summary>\n        /// Sets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application.\n        /// </summary>\n        /// <param name = \"appsFlyerConsent\" >instance of AppsFlyerConsent.</param>\n        public void setConsentData(AppsFlyerConsent appsFlyerConsent)\n        {\n#if !UNITY_EDITOR\n           string isUserSubjectToGDPR = appsFlyerConsent.isUserSubjectToGDPR?.ToString().ToLower() ?? \"null\";\n           string hasConsentForDataUsage = appsFlyerConsent.hasConsentForDataUsage?.ToString().ToLower() ?? \"null\";\n           string hasConsentForAdsPersonalization = appsFlyerConsent.hasConsentForAdsPersonalization?.ToString().ToLower() ?? \"null\";\n           string hasConsentForAdStorage = appsFlyerConsent.hasConsentForAdStorage?.ToString().ToLower() ?? \"null\";\n\n           _setConsentData(isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization, hasConsentForAdStorage);\n#endif\n         }\n\n        /// <summary>\n        /// Logs ad revenue data along with additional parameters if provided.\n        /// </summary>\n        /// <param name = \"adRevenueData\" >instance of AFAdRevenueData containing ad revenue information.</param>\n        /// <param name = \"additionalParameters\" >An optional map of additional parameters to be logged with ad revenue data. This can be null if there are no additional parameters.</param>\n        public void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters)\n        {\n#if !UNITY_EDITOR\n            _logAdRevenue(adRevenueData.monetizationNetwork, adRevenueData.mediationNetwork, adRevenueData.currencyIso4217Code, adRevenueData.eventRevenue, AFMiniJSON.Json.Serialize(additionalParameters));\n#endif\n         }\n\n        /// <summary>\n        /// Anonymize user Data.\n        /// Use this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions.\n        /// Default is false\n        /// </summary>\n        /// <param name=\"shouldAnonymizeUser\">boolean shouldAnonymizeUser.</param>\n        public void anonymizeUser(bool shouldAnonymizeUser)\n        {\n#if !UNITY_EDITOR\n           _anonymizeUser(shouldAnonymizeUser);\n#endif\n        }\n\n        /// <summary>\n        /// Opt-out for Apple Search Ads attributions.\n        /// </summary>\n        /// <param name=\"disableCollectIAd\">boolean disableCollectIAd.</param>\n        public void setDisableCollectIAd(bool disableCollectIAd)\n        {\n#if !UNITY_EDITOR\n           _setDisableCollectIAd(disableCollectIAd);\n#endif\n        }\n\n        /// <summary>\n        /// In app purchase receipt validation Apple environment(production or sandbox). The default value is false.\n        /// </summary>\n        /// <param name=\"useReceiptValidationSandbox\">boolean useReceiptValidationSandbox.</param>\n        public void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox)\n        {\n#if !UNITY_EDITOR\n            _setUseReceiptValidationSandbox(useReceiptValidationSandbox);\n#endif\n        }\n\n        /// <summary>\n        /// Set this flag to test uninstall on Apple environment(production or sandbox). The default value is false.\n        /// </summary>\n        /// <param name=\"useUninstallSandbox\">boolean useUninstallSandbox.</param>\n        public void setUseUninstallSandbox(bool useUninstallSandbox)\n        {\n#if !UNITY_EDITOR\n           _setUseUninstallSandbox(useUninstallSandbox);\n#endif\n        }\n\n        /// <summary>\n        /// For advertisers who wrap OneLink within another Universal Link.\n        /// An advertiser will be able to deeplink from a OneLink wrapped within another Universal Link and also record this retargeting conversion.\n        /// </summary>\n        /// <param name=\"resolveDeepLinkURLs\">Array of urls.</param>\n        public void setResolveDeepLinkURLs(params string[] resolveDeepLinkURLs)\n        {\n#if !UNITY_EDITOR\n           _setResolveDeepLinkURLs(resolveDeepLinkURLs.Length,resolveDeepLinkURLs);\n#endif\n        }\n\n        /// <summary>\n        /// For advertisers who use vanity OneLinks.\n        /// </summary>\n        /// <param name=\"oneLinkCustomDomains\">Array of domains.</param>\n        public void setOneLinkCustomDomain(params string[] oneLinkCustomDomains)\n        {\n#if !UNITY_EDITOR\n            _setOneLinkCustomDomains(oneLinkCustomDomains.Length, oneLinkCustomDomains);\n#endif\n        }\n\n        /// <summary>\n        /// Set the user emails and encrypt them.\n        /// cryptMethod Encryption method:\n        /// EmailCryptType.EmailCryptTypeMD5\n        /// EmailCryptType.EmailCryptTypeSHA1\n        /// EmailCryptType.EmailCryptTypeSHA256\n        /// EmailCryptType.EmailCryptTypeNone\n        /// </summary>\n        /// <param name=\"cryptType\">type Hash algoritm.</param>\n        /// <param name=\"length\">length of userEmails array.</param>\n        /// <param name=\"userEmails\">userEmails The list of strings that hold mails.</param>}\n\n        public void setUserEmails(EmailCryptType cryptType, params string[] userEmails)\n        {\n#if !UNITY_EDITOR\n           _setUserEmails(cryptType, userEmails.Length, userEmails);\n#endif\n        }\n\n        /// <summary>\n        /// Set the user phone number.\n        /// </summary>\n        /// <param name=\"phoneNumber\">User phoneNumber.</param>\n        public void setPhoneNumber(string phoneNumber){\n#if !UNITY_EDITOR\n            _setPhoneNumber(phoneNumber);\n#endif\n        }\n\n        /// <summary>\n        /// [Deprecated] To send and validate in app purchases - please use V2 with AFSDKPurchaseDetailsIOS instead.\n        /// </summary>\n        /// <param name=\"productIdentifier\">The product identifier.</param>\n        /// <param name=\"price\">The product price.</param>\n        /// <param name=\"currency\">The product currency.</param>\n        /// <param name=\"transactionId\">The purchase transaction Id.</param>\n        /// <param name=\"additionalParameters\">The additional param, which you want to receive it in the raw reports.</param>\n        [System.Obsolete(\"This method is deprecated. Use validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject) instead.\")]\n        public void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            _validateAndSendInAppPurchase(productIdentifier, price, currency, transactionId, AFMiniJSON.Json.Serialize(additionalParameters), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// V2 - To send and validate in app purchases you can call this method from the processPurchase method.\n        /// </summary>\n        /// <param name=\"details\">The AFSDKPurchaseDetailsIOS instance.</param>\n        /// <param name=\"purchaseAdditionalDetails\">The additional params, which you want to receive it in the raw reports.</param>\n        public void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            _validateAndSendInAppPurchaseV2(details.productId, details.transactionId, (int)details.purchaseType, AFMiniJSON.Json.Serialize(purchaseAdditionalDetails), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// To record location for geo-fencing. Does the same as code below.\n        /// </summary>\n        /// <param name=\"longitude\">The location longitude.</param>\n        /// <param name=\"latitude\">The location latitude.</param>\n        public void recordLocation(double longitude, double latitude)\n        {\n#if !UNITY_EDITOR\n            _recordLocation(longitude, latitude);\n#endif\n        }\n\n        /// <summary>\n        /// Get AppsFlyer's unique device ID, which is created for every new install of an app.\n        /// </summary>\n        public string getAppsFlyerId()\n        {\n#if !UNITY_EDITOR\n           return _getAppsFlyerId();\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// Register uninstall - you should register for remote notification and provide AppsFlyer the push device token.\n        /// </summary>\n        /// <param name=\"deviceToken\">deviceToken The `deviceToken` from `-application:didRegisterForRemoteNotificationsWithDeviceToken:`.</param>\n        public void registerUninstall(byte[] deviceToken)\n        {\n#if !UNITY_EDITOR\n           _registerUninstall(deviceToken);\n#endif\n        }\n\n        /// <summary>\n        /// Enable AppsFlyer to handle a push notification.\n        /// </summary>\n        /// <param name=\"pushPayload\">pushPayload The `userInfo` from received remote notification. One of root keys should be @\"af\"..</param>\n        public void handlePushNotification(Dictionary<string, string> pushPayload)\n        {\n#if !UNITY_EDITOR\n           _handlePushNotification(AFMiniJSON.Json.Serialize(pushPayload));\n#endif\n        }\n\n        /// <summary>\n        /// Get SDK version.\n        /// </summary>\n        public string getSdkVersion()\n        {\n#if !UNITY_EDITOR\n           return _getSDKVersion();\n#else\n            return \"\";\n#endif\n        }\n\n        /// <summary>\n        /// This property accepts a string value representing the host name for all endpoints.\n        /// Can be used to Zero rate your application’s data usage.Contact your CSM for more information.\n        /// </summary>\n        /// <param name=\"host\">Host Name.</param>\n        /// <param name=\"host\">Host prefix.</param>\n        public void setHost(string hostPrefix, string host)\n        {\n#if !UNITY_EDITOR\n            _setHost(host, hostPrefix);\n#endif\n        }\n\n        /// <summary>\n        /// This property is responsible for timeout between sessions in seconds.\n        /// Default value is 5 seconds.\n        /// </summary>\n        /// <param name=\"minTimeBetweenSessions\">minimum time between 2 separate sessions in seconds.</param>\n        public void setMinTimeBetweenSessions(int minTimeBetweenSessions)\n        {\n#if !UNITY_EDITOR\n           _setMinTimeBetweenSessions(minTimeBetweenSessions);\n#endif\n        }\n\n        /// <summary>\n        /// Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.\n        /// In some extreme cases you might want to shut down all SDK activity due to legal and privacy compliance.\n        /// This can be achieved with the stopSDK API.\n        /// </summary>\n        /// <param name=\"isSDKStopped\">boolean isSDKStopped.</param>\n        public void stopSDK(bool isSDKStopped)\n        {\n#if !UNITY_EDITOR\n            _stopSDK(isSDKStopped);\n#endif\n        }\n\n        // <summary>\n        /// Was the stopSDK(boolean) API set to true.\n        /// </summary>\n        /// <returns>boolean isSDKStopped.</returns>\n        public bool isSDKStopped()\n        {\n#if !UNITY_EDITOR\n           return _isSDKStopped();\n#else\n            return false;\n#endif\n        }\n\n        /// <summary>\n        /// In case you want to track deep linking manually call handleOpenUrl.\n        /// The continueUserActivity and onOpenURL are implemented in the AppsFlyerAppController.mm class, so \n        /// only use this method if the other methods do not cover your apps deeplinking needs.\n        /// </summary>\n        /// <param name=\"url\">The URL to be passed to your AppDelegate.</param>\n        /// <param name=\"sourceApplication\">The sourceApplication to be passed to your AppDelegate.</param>\n        /// <param name=\"annotation\">The annotation to be passed to your app delegate.</param>\n        public void handleOpenUrl(string url, string sourceApplication, string annotation)\n        {\n#if !UNITY_EDITOR\n            _handleOpenUrl(url, sourceApplication, annotation);\n#endif\n        }\n\n        /// <summary>\n        /// Used by advertisers to exclude all networks/integrated partners from getting data.\n        /// </summary>\n        public void setSharingFilterForAllPartners()\n        {\n#if !UNITY_EDITOR\n            _setSharingFilterForAllPartners();\n#endif\n        }\n\n        /// <summary>\n        /// Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.\n        /// </summary>\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        public void setSharingFilter(params string[] partners)\n        {\n#if !UNITY_EDITOR\n            _setSharingFilter(partners.Length, partners);\n#endif\n        }\n\n\n        /// <summary>\n        /// Lets you configure how which partners should the SDK exclude from data-sharing.\n        /// <param name=\"partners\">partners to exclude from getting data</param>\n        public static void setSharingFilterForPartners(params string[] partners)\n        {\n#if !UNITY_EDITOR\n            _setSharingFilterForPartners(partners.Length, partners);\n#endif\n        }\n\n        /// <summary>\n        /// To record an impression use the following API call.\n        /// Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.\n        /// </summary>\n        /// <param name=\"appID\">promoted App ID.</param>\n        /// <param name=\"campaign\">cross promotion campaign.</param>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters)\n        {\n#if !UNITY_EDITOR\n            _recordCrossPromoteImpression(appID, campaign, AFMiniJSON.Json.Serialize(parameters));\n#endif\n        }\n\n        /// <summary>\n        /// Use the following API to attribute the click and launch the app store's app page.\n        /// </summary>\n        /// <param name=\"appID\">promoted App ID</param>\n        /// <param name=\"campaign\">cross promotion campaign</param>\n        /// <param name=\"parameters\">additional user params</param>\n        public void attributeAndOpenStore(string appID, string campaign, Dictionary<string, string> parameters, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n           _attributeAndOpenStore(appID, campaign, AFMiniJSON.Json.Serialize(parameters), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// The LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click.\n        /// See - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution-\n        /// </summary>\n        /// <param name=\"parameters\">parameters Dictionary.</param>\n        public void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject)\n        {\n#if !UNITY_EDITOR\n            _generateUserInviteLink(AFMiniJSON.Json.Serialize(parameters), gameObject ? gameObject.name : null);\n#endif\n        }\n\n        /// <summary>\n        /// It is recommended to generate an in-app event after the invite is sent to record the invites from the senders' perspective. \n        /// This enables you to find the users that tend most to invite friends, and the media sources that get you these users.\n        /// </summary>\n        /// <param name=\"channel\">channel string.</param>\n        /// <param name=\"parameters\">parameters Dictionary..</param>\n        public void recordInvite(string channel, Dictionary<string, string> parameters)\n        {\n#if !UNITY_EDITOR\n            _recordInvite(channel, AFMiniJSON.Json.Serialize(parameters));\n#endif\n        }\n\n        /// <summary>\n        /// Waits for request user authorization to access app-related data\n        /// </summary>\n        /// <param name=\"timeoutInterval\">time to wait until session starts</param>\n        public void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval)\n        {\n#if !UNITY_EDITOR\n             _waitForATTUserAuthorizationWithTimeoutInterval(timeoutInterval);\n#endif\n        }\n\n        /// <summary>\n        /// </summary>\n        /// <param name=\"isDisabled\">bool should diable</param>\n        public void disableSKAdNetwork(bool isDisabled)\n        {\n#if !UNITY_EDITOR\n            _disableSKAdNetwork(isDisabled);\n#endif\n        }\n\n        /// <summary>\n        /// Use this method if you’re integrating your app with push providers \n        /// that don’t use the default push notification JSON schema the SDK expects.\n        /// See docs for more info.\n        /// </summary>\n        /// <param name=\"paths\">array of nested json path</param>\n        public void addPushNotificationDeepLinkPath(params string[] paths)\n        {\n#if !UNITY_EDITOR\n            _addPushNotificationDeepLinkPath(paths.Length, paths);\n#endif\n        }\n\n        /// <summary>\n        /// subscribe to unified deep link callbacks\n        /// </summary>\n        public void subscribeForDeepLink(string objectName){\n#if !UNITY_EDITOR\n            _subscribeForDeepLink(objectName);\n#endif\n        }\n\n           /// <summary>\n        /// Set the language of the device.\n        /// </summary>\n        public void setCurrentDeviceLanguage(string language){\n#if !UNITY_EDITOR\n            _setCurrentDeviceLanguage(language);\n#endif\n        }\n\n        /// <summary>\n        /// Allows sending custom data for partner integration purposes.\n        /// </summary>\n        public void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo){\n#if !UNITY_EDITOR\n            _setPartnerData(partnerId, AFMiniJSON.Json.Serialize(partnerInfo));\n#endif\n        }\n\n        /// <summary>\n        /// Use to disable app vendor identifier (IDFV) collection, 'true' to disable.\n        /// </summary>\n        public void disableIDFVCollection(bool isDisabled){\n#if !UNITY_EDITOR\n            _disableIDFVCollection(isDisabled);\n#endif\n        }\n\n        delegate void unityCallBack(string message);\n\n        [AOT.MonoPInvokeCallback(typeof(unityCallBack))]\n        public static void getCallback(string gameObjectName, string callbackName, string message)\n        {\n            GameObject go = GameObject.Find(\"AppsFlyerObject\");\n            var afscript = go.GetComponent(\"AppsFlyerObjectScript\") as AppsFlyerObjectScript;\n            Type type = typeof(AppsFlyerObjectScript);\n            MethodInfo info = type.GetMethod(callbackName);\n            info.Invoke(afscript, new[] { message });\n            \n        }\n\n\n        /*\n         * AppsFlyer ios method mapping\n         */\n\n\n#if UNITY_IOS\n     [DllImport(\"__Internal\")]\n        private static extern void _startSDK(bool shouldCallback, string objectName);\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n        private static extern void _startSDK(bool shouldCallback, string objectName, Action<string, string, string> getCallback);\n\n#endif\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _getConversionData(string objectName);\n\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setCustomerUserID(string customerUserID);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setAdditionalData(string customData);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setAppsFlyerDevKey(string appsFlyerDevKey);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setAppleAppID(string appleAppID);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setCurrencyCode(string currencyCode);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setDisableCollectAppleAdSupport(bool disableCollectAppleAdSupport);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setIsDebug(bool isDebug);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setShouldCollectDeviceName(bool shouldCollectDeviceName);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setAppInviteOneLinkID(string appInviteOneLinkID);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setDeepLinkTimeout(long deepLinkTimeout);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _anonymizeUser(bool shouldAnonymizeUser);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _enableTCFDataCollection(bool shouldCollectTcfData);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setConsentData(string isUserSubjectToGDPR, string hasConsentForDataUsage, string hasConsentForAdsPersonalization, string hasConsentForAdStorage);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _logAdRevenue(string monetizationNetwork, MediationNetwork mediationNetwork, string currencyIso4217Code, double eventRevenue, string additionalParameters);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setDisableCollectIAd(bool disableCollectIAd);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setUseReceiptValidationSandbox(bool useReceiptValidationSandbox);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setUseUninstallSandbox(bool useUninstallSandbox);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setResolveDeepLinkURLs(int length, params string[] resolveDeepLinkURLs);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setOneLinkCustomDomains(int length, params string[] oneLinkCustomDomains);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setUserEmails(EmailCryptType cryptType, int length, params string[] userEmails);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setPhoneNumber(string phoneNumber);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _afSendEvent(string eventName, string eventValues, bool shouldCallback, string objectName);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, string additionalParameters, string objectName);\n\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _validateAndSendInAppPurchaseV2(string product, string transactionId, int purchaseType, string purchaseAdditionalDetails, string objectName);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _recordLocation(double longitude, double latitude);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern string _getAppsFlyerId();\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _registerUninstall(byte[] deviceToken);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _handlePushNotification(string pushPayload);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern string _getSDKVersion();\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setHost(string host, string hostPrefix);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setMinTimeBetweenSessions(int minTimeBetweenSessions);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _stopSDK(bool isStopSDK);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern bool _isSDKStopped();\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _handleOpenUrl(string url, string sourceApplication, string annotation);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setSharingFilterForAllPartners();\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setSharingFilter(int length, params string[] partners);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setSharingFilterForPartners(int length, params string[] partners);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _recordCrossPromoteImpression(string appID, string campaign, string parameters);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _attributeAndOpenStore(string appID, string campaign, string parameters, string gameObject);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _generateUserInviteLink(string parameters, string gameObject);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _recordInvite(string channel, string parameters);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _disableSKAdNetwork(bool isDisabled);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _addPushNotificationDeepLinkPath(int length, params string[] paths);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _subscribeForDeepLink(string objectName);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setCurrentDeviceLanguage(string language);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _setPartnerData(string partnerId, string partnerInfo);\n\n#if UNITY_IOS\n    [DllImport(\"__Internal\")]\n#elif UNITY_STANDALONE_OSX\n        [DllImport(\"AppsFlyerBundle\")]\n#endif\n        private static extern void _disableIDFVCollection(bool isDisabled);\n\n    }\n\n#endif\n\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/AppsFlyeriOS.cs.meta",
    "content": "fileFormatVersion: 2\nguid: b34371b3cc09641ebb007ffc4e9500f0\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyer.Editor.asmdef",
    "content": "{\n    \"name\": \"AppsFlyer.Editor\",\n    \"references\": [\n        \"AppsFlyer\"\n    ],\n    \"includePlatforms\": [\n        \"Editor\"\n    ],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": false,\n    \"precompiledReferences\": [],\n    \"autoReferenced\": true,\n    \"defineConstraints\": [],\n    \"versionDefines\": [],\n    \"noEngineReferences\": false\n}"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyer.Editor.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: d008146f00dea44d38752b4289e5f65b\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<dependencies>\n\n  <androidPackages>\n    <androidPackage spec=\"com.appsflyer:af-android-sdk:6.17.6\"></androidPackage>\n    <androidPackage spec=\"com.appsflyer:unity-wrapper:6.17.91\"></androidPackage>\n    <androidPackage spec=\"com.android.installreferrer:installreferrer:2.1\"></androidPackage>\n    <androidPackage spec=\"com.appsflyer:purchase-connector:2.2.0\"></androidPackage>\n  </androidPackages>\n\n  <iosPods>\n    <iosPod name=\"AppsFlyerFramework\" version=\"6.17.9\" minTargetSdk=\"12.0\"></iosPod>\n    <iosPod name=\"PurchaseConnector\" version=\"6.17.9\" minTargetSdk=\"12.0\"></iosPod>\n  </iosPods>\n\n</dependencies>\n"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml.meta",
    "content": "fileFormatVersion: 2\nguid: a03558dbbfeac45db9afe9e9c2df5a85\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyerObjectEditor.cs",
    "content": "using UnityEditor;\nusing UnityEngine;\n\n\n[CustomEditor(typeof(AppsFlyerObjectScript))]\n[CanEditMultipleObjects]\npublic class AppsFlyerObjectEditor : Editor\n{\n\n    SerializedProperty devKey;\n    SerializedProperty appID;\n    SerializedProperty UWPAppID;\n    SerializedProperty macOSAppID;\n    SerializedProperty isDebug;\n    SerializedProperty getConversionData;\n\n\n    void OnEnable()\n    {\n        devKey = serializedObject.FindProperty(\"devKey\");\n        appID = serializedObject.FindProperty(\"appID\");\n        UWPAppID = serializedObject.FindProperty(\"UWPAppID\");\n        macOSAppID = serializedObject.FindProperty(\"macOSAppID\");\n        isDebug = serializedObject.FindProperty(\"isDebug\");\n        getConversionData = serializedObject.FindProperty(\"getConversionData\");\n    }\n\n\n\n    public override void OnInspectorGUI()\n    {\n        serializedObject.Update();\n\n        DrawLogo();\n\n        EditorGUILayout.Separator();\n        EditorGUILayout.HelpBox(\"Set your devKey and appID to init the AppsFlyer SDK and start tracking. You must modify these fields and provide:\\ndevKey - Your application devKey provided by AppsFlyer.\\nappId - For iOS only. Your iTunes Application ID.\\nUWP app id - For UWP only. Your application app id \\nMac OS app id - For MacOS app only.\", MessageType.Info);\n\n        EditorGUILayout.PropertyField(devKey);\n        EditorGUILayout.PropertyField(appID);\n        EditorGUILayout.PropertyField(UWPAppID);\n        EditorGUILayout.PropertyField(macOSAppID);\n        EditorGUILayout.Separator();\n        EditorGUILayout.HelpBox(\"Enable get conversion data to allow your app to recive deeplinking callbacks\", MessageType.None);\n        EditorGUILayout.PropertyField(getConversionData);\n        EditorGUILayout.Separator();\n        EditorGUILayout.HelpBox(\"Debugging should be restricted to development phase only.\\n Do not distribute the app to app stores with debugging enabled\", MessageType.Warning);\n        EditorGUILayout.PropertyField(isDebug);\n        EditorGUILayout.Separator();\n\n        EditorGUILayout.HelpBox(\"For more information on setting up AppsFlyer check out our relevant docs.\", MessageType.None);\n\n   \n        if (GUILayout.Button(\"AppsFlyer Unity Docs\", new GUILayoutOption[] { GUILayout.Width(200) }))\n        {\n            Application.OpenURL(\"https://support.appsflyer.com/hc/en-us/articles/213766183-Unity-SDK-integration-for-developers\");\n        }\n\n        if (GUILayout.Button(\"AppsFlyer Android Docs\", new GUILayoutOption[] { GUILayout.Width(200) }))\n        {\n            Application.OpenURL(\"https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers\");\n        }\n\n        if (GUILayout.Button(\"AppsFlyer iOS Docs\", new GUILayoutOption[] { GUILayout.Width(200) }))\n        {\n            Application.OpenURL(\"https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS\");\n        }\n\n        if (GUILayout.Button(\"AppsFlyer Deeplinking Docs\", new GUILayoutOption[] { GUILayout.Width(200) }))\n        {\n            Application.OpenURL(\"https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-deep-linking-guide#Setups\");\n        }\n\n        if (GUILayout.Button(\"AppsFlyer Windows Docs\", new GUILayoutOption[] { GUILayout.Width(200) }))\n        {\n            Application.OpenURL(\"https://support.appsflyer.com/hc/en-us/articles/207032026-Windows-and-Xbox-SDK-integration-for-developers\");\n        }\n\n\n        serializedObject.ApplyModifiedProperties();\n    }\n\n    private void DrawLogo()\n    {\n        var guids = AssetDatabase.FindAssets(\"appsflyer_logo\");\n        if (guids.Length == 0) return;\n\n        Texture logo = (Texture)AssetDatabase.LoadAssetAtPath(\n            AssetDatabase.GUIDToAssetPath(guids[0]),\n            typeof(Texture));\n\n        if (logo == null) return;\n\n        float maxWidth = Mathf.Min(200, EditorGUIUtility.currentViewWidth - 40);\n        float aspect = (float)logo.height / logo.width;\n        float height = maxWidth * aspect;\n\n        Rect rect = GUILayoutUtility.GetRect(maxWidth, height, GUILayout.ExpandWidth(false));\n        rect.x = (EditorGUIUtility.currentViewWidth - maxWidth) * 0.5f;\n        rect.width = maxWidth;\n        GUI.DrawTexture(rect, logo, ScaleMode.ScaleToFit);\n    }\n\n}"
  },
  {
    "path": "Assets/AppsFlyer/Editor/AppsFlyerObjectEditor.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d248a134cf494486fb1d6a2e95a05d87\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Editor/appsflyer_logo.png.meta",
    "content": "fileFormatVersion: 2\nguid: bc7fa5a6b64b944a4b2900fd877acb8b\nTextureImporter:\n  internalIDToNameTable: []\n  externalObjects: {}\n  serializedVersion: 11\n  mipmaps:\n    mipMapMode: 0\n    enableMipMap: 1\n    sRGBTexture: 1\n    linearTexture: 0\n    fadeOut: 0\n    borderMipMap: 0\n    mipMapsPreserveCoverage: 0\n    alphaTestReferenceValue: 0.5\n    mipMapFadeDistanceStart: 1\n    mipMapFadeDistanceEnd: 3\n  bumpmap:\n    convertToNormalMap: 0\n    externalNormalMap: 0\n    heightScale: 0.25\n    normalMapFilter: 0\n  isReadable: 0\n  streamingMipmaps: 0\n  streamingMipmapsPriority: 0\n  grayScaleToAlpha: 0\n  generateCubemap: 6\n  cubemapConvolution: 0\n  seamlessCubemap: 0\n  textureFormat: 1\n  maxTextureSize: 2048\n  textureSettings:\n    serializedVersion: 2\n    filterMode: -1\n    aniso: -1\n    mipBias: -100\n    wrapU: -1\n    wrapV: -1\n    wrapW: -1\n  nPOTScale: 1\n  lightmap: 0\n  compressionQuality: 50\n  spriteMode: 0\n  spriteExtrude: 1\n  spriteMeshType: 1\n  alignment: 0\n  spritePivot: {x: 0.5, y: 0.5}\n  spritePixelsToUnits: 100\n  spriteBorder: {x: 0, y: 0, z: 0, w: 0}\n  spriteGenerateFallbackPhysicsShape: 1\n  alphaUsage: 1\n  alphaIsTransparency: 0\n  spriteTessellationDetail: -1\n  textureType: 0\n  textureShape: 1\n  singleChannelComponent: 0\n  maxTextureSizeSet: 0\n  compressionQualitySet: 0\n  textureFormatSet: 0\n  applyGammaDecoding: 0\n  platformSettings:\n  - serializedVersion: 3\n    buildTarget: DefaultTexturePlatform\n    maxTextureSize: 2048\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  spriteSheet:\n    serializedVersion: 2\n    sprites: []\n    outline: []\n    physicsShape: []\n    bones: []\n    spriteID: \n    internalID: 0\n    vertices: []\n    indices: \n    edges: []\n    weights: []\n    secondaryTextures: []\n  spritePackingTag: \n  pSDRemoveMatte: 0\n  pSDShowRemoveMatteOption: 0\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Editor.meta",
    "content": "fileFormatVersion: 2\nguid: 9f84c02aa78da4ac9b444d98d97f7cc4\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerAndroidBridge.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace AppsFlyerSDK\n{\n\n    public interface IAppsFlyerAndroidBridge : IAppsFlyerNativeBridge\n    {\n        void updateServerUninstallToken(string token);\n        void setImeiData(string imei);\n        void setAndroidIdData(string androidId);\n        void waitForCustomerUserId(bool wait);\n        void setCustomerIdAndStartSDK(string id);\n        string getOutOfStore();\n        void setOutOfStore(string sourceName);\n        void setCollectAndroidID(bool isCollect);\n        void setCollectIMEI(bool isCollect);\n        void setIsUpdate(bool isUpdate);\n        void setPreinstallAttribution(string mediaSource, string campaign, string siteId);\n        bool isPreInstalledApp();\n        string getAttributionId();\n        void handlePushNotifications();\n        void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject);\n        void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject);\n        void setCollectOaid(bool isCollect);\n        void setDisableAdvertisingIdentifiers(bool disable);\n        void setDisableNetworkData(bool disable);\n\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerAndroidBridge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: cdf9d1bc41a8244b3bc2d249fb6cd7aa\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerConversionData.cs",
    "content": "namespace AppsFlyerSDK\n{\n    public interface IAppsFlyerConversionData\n    {\n        /// <summary>\n        ///  `conversionData` contains information about install. Organic/non-organic, etc.\n        /// <see>https://support.appsflyer.com/hc/en-us/articles/360000726098-Conversion-Data-Scenarios#Introduction</see>\n        /// </summary>\n        /// <param name=\"conversionData\">JSON string of the returned conversion data.</param>\n        void onConversionDataSuccess(string conversionData);\n\n        /// <summary>\n        /// Any errors that occurred during the conversion request.\n        /// </summary>\n        /// <param name=\"error\">A string describing the error.</param>\n        void onConversionDataFail(string error);\n\n        /// <summary>\n        /// `attributionData` contains information about OneLink, deeplink.\n        /// <see>https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-Deep-Linking-Guide#Intro</see>\n        /// </summary>\n        /// <param name=\"attributionData\">JSON string of the returned deeplink data.</param>\n        void onAppOpenAttribution(string attributionData);\n\n        /// <summary>\n        /// Any errors that occurred during the attribution request.\n        /// </summary>\n        /// <param name=\"error\">A string describing the error.</param>\n        void onAppOpenAttributionFailure(string error);\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerConversionData.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d2f1d4dadb7cb44628f25f1ffd8fc104\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerIOSBridge.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\n\nnamespace AppsFlyerSDK\n{\n\n\tpublic interface IAppsFlyerIOSBridge : IAppsFlyerNativeBridge\n\t{\n        void setDisableCollectAppleAdSupport(bool disable);\n\t\tvoid setShouldCollectDeviceName(bool shouldCollectDeviceName);\n\t\tvoid setDisableCollectIAd(bool disableCollectIAd);\n\t\tvoid setUseReceiptValidationSandbox(bool useReceiptValidationSandbox);\n\t\tvoid setUseUninstallSandbox(bool useUninstallSandbox);\n\t\tvoid validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject);\n\t\tvoid validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject);\n\t\tvoid registerUninstall(byte[] deviceToken);\n\t\tvoid handleOpenUrl(string url, string sourceApplication, string annotation);\n\t\tvoid waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval);\n\t\tvoid setCurrentDeviceLanguage(string language);\n\t\tvoid disableSKAdNetwork(bool isDisabled);\n\t\tvoid disableIDFVCollection(bool isDisabled);\n\n\t}\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerIOSBridge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6847fb337898040288c165e3667101a3\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerNativeBridge.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace AppsFlyerSDK\n{\n\n    public interface IAppsFlyerNativeBridge\n    {\n        bool isInit { get; set; }\n\n        void startSDK(bool onRequestResponse, string CallBackObjectName);\n\n        void sendEvent(string eventName, Dictionary<string, string> eventValues, bool onInAppResponse, string CallBackObjectName);\n\n        void stopSDK(bool isSDKStopped);\n\n        bool isSDKStopped();\n\n        string getSdkVersion();\n\n        void setCustomerUserId(string id);\n\n        void setAppInviteOneLinkID(string oneLinkId);\n\n        void setAdditionalData(Dictionary<string, string> customData);\n\n        void setDeepLinkTimeout(long deepLinkTimeout);\n\n        void setResolveDeepLinkURLs(params string[] urls);\n\n        void setOneLinkCustomDomain(params string[] domains);\n\n        void setCurrencyCode(string currencyCode);\n\n        void recordLocation(double latitude, double longitude);\n\n        void anonymizeUser(bool shouldAnonymizeUser);\n\n        string getAppsFlyerId();\n\n        void enableTCFDataCollection(bool shouldCollectTcfData);\n\n        void setConsentData(AppsFlyerConsent appsFlyerConsent);\n\n        void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters);\n\n        void setMinTimeBetweenSessions(int seconds);\n\n        void setHost(string hostPrefixName, string hostName);\n\n        void setPhoneNumber(string phoneNumber);\n\n        void setSharingFilterForAllPartners();\n\n        void setSharingFilter(params string[] partners);\n\n        void getConversionData(string objectName);\n\n        void attributeAndOpenStore(string appID, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject);\n\n        void recordCrossPromoteImpression(string appID, string campaign, Dictionary<string, string> parameters);\n\n        void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject);\n\n        void addPushNotificationDeepLinkPath(params string[] paths);\n\n        void setUserEmails(EmailCryptType cryptType, params string[] userEmails);\n\n        void subscribeForDeepLink(string objectName);\n\n        void setIsDebug(bool shouldEnable);\n\n        void setPartnerData(string partnerId, Dictionary<string, string> partnerInfo);\n    }\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerNativeBridge.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 409b8302434664a3785ce55d075e7f58\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerPurchaseValidation.cs",
    "content": "namespace AppsFlyerSDK\n{\n    public interface IAppsFlyerPurchaseValidation\n    {\n        void didReceivePurchaseRevenueValidationInfo(string validationInfo);\n        void didReceivePurchaseRevenueError(string error);\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerPurchaseValidation.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7c60f499ae0d048b1be8ffd6878a184c\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerUserInvite.cs",
    "content": "namespace AppsFlyerSDK\n{\n    public interface IAppsFlyerUserInvite\n    {\n        /// <summary>\n        /// The success callback for generating OneLink URLs. \n        /// </summary>\n        /// <param name=\"link\">A string of the newly created url.</param>\n        void onInviteLinkGenerated(string link);\n\n        /// <summary>\n        /// The error callback for generating OneLink URLs\n        /// </summary>\n        /// <param name=\"error\">A string describing the error.</param>\n        void onInviteLinkGeneratedFailure(string error);\n\n        /// <summary>\n        /// (ios only) iOS allows you to utilize the StoreKit component to open\n        /// the App Store while remaining in the context of your app.\n        /// More details at <see>https://support.appsflyer.com/hc/en-us/articles/115004481946-Cross-Promotion-Tracking#tracking-cross-promotion-impressions</see>\n        /// </summary>\n        /// <param name=\"link\">openStore callback Contains promoted `clickURL`</param>\n        void onOpenStoreLinkGenerated(string link);\n\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerUserInvite.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 5a4cdfa023cb8497b94bb39720052fef\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerValidateAndLog.cs",
    "content": "namespace AppsFlyerSDK\n{\n    public interface IAppsFlyerValidateAndLog\n    {\n        /// <summary>\n        /// The success callback for validateAndSendInAppPurchase API.\n        /// For Android : the callback will return JSON string.\n        /// For iOS : the callback will return a JSON string from apples verifyReceipt API.\n        /// </summary>\n        /// <param name=\"result\"></param>\n        void onValidateAndLogComplete(string result);\n\n        /// <summary>\n        /// The error callback for validateAndSendInAppPurchase API.\n        /// </summary>\n        /// <param name=\"error\">A string describing the error.</param>\n        void onValidateAndLogFailure(string error);\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerValidateAndLog.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1a5adb7eab3284dd39a76ec56c06457c\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerValidateReceipt.cs",
    "content": "namespace AppsFlyerSDK\n{\n    public interface IAppsFlyerValidateReceipt\n    {\n        /// <summary>\n        /// The success callback for validateAndSendInAppPurchase API.\n        /// For Android : the callback will return \"Validate success\".\n        /// For iOS : the callback will return a JSON string from apples verifyReceipt API.\n        /// </summary>\n        /// <param name=\"result\"></param>\n        void didFinishValidateReceipt(string result);\n\n        /// <summary>\n        /// The error callback for validateAndSendInAppPurchase API.\n        /// </summary>\n        /// <param name=\"error\">A string describing the error.</param>\n        void didFinishValidateReceiptWithError(string error);\n    }\n}"
  },
  {
    "path": "Assets/AppsFlyer/IAppsFlyerValidateReceipt.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6385b1d184efa400a98515735e1f17bc\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/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\t<key>BuildMachineOSBuild</key>\n\t<string>20G417</string>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>AppsFlyerBundle</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.appsflyer.support.two.AppsFlyerBundle</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>AppsFlyerBundle</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSupportedPlatforms</key>\n\t<array>\n\t\t<string>MacOSX</string>\n\t</array>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>DTCompiler</key>\n\t<string>com.apple.compilers.llvm.clang.1_0</string>\n\t<key>DTPlatformBuild</key>\n\t<string>13A1030d</string>\n\t<key>DTPlatformName</key>\n\t<string>macosx</string>\n\t<key>DTPlatformVersion</key>\n\t<string>12.0</string>\n\t<key>DTSDKBuild</key>\n\t<string>21A344</string>\n\t<key>DTSDKName</key>\n\t<string>macosx12.0</string>\n\t<key>DTXcode</key>\n\t<string>1310</string>\n\t<key>DTXcodeBuild</key>\n\t<string>13A1030d</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>11.6</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/Info.plist.meta",
    "content": "fileFormatVersion: 2\nguid: 58a86b0b376564c06bf8ce29e1dbfb04\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/MacOS/AppsFlyerBundle.meta",
    "content": "fileFormatVersion: 2\nguid: 0889edee891d84a8eb0b7cc87071b91e\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/MacOS.meta",
    "content": "fileFormatVersion: 2\nguid: 218a2e7ff5a4c461981bc41f7d7bfeba\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature/CodeResources",
    "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\t<key>files</key>\n\t<dict/>\n\t<key>files2</key>\n\t<dict/>\n\t<key>rules</key>\n\t<dict>\n\t\t<key>^Resources/</key>\n\t\t<true/>\n\t\t<key>^Resources/.*\\.lproj/</key>\n\t\t<dict>\n\t\t\t<key>optional</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>1000</real>\n\t\t</dict>\n\t\t<key>^Resources/.*\\.lproj/locversion.plist$</key>\n\t\t<dict>\n\t\t\t<key>omit</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>1100</real>\n\t\t</dict>\n\t\t<key>^Resources/Base\\.lproj/</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>1010</real>\n\t\t</dict>\n\t\t<key>^version.plist$</key>\n\t\t<true/>\n\t</dict>\n\t<key>rules2</key>\n\t<dict>\n\t\t<key>.*\\.dSYM($|/)</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>11</real>\n\t\t</dict>\n\t\t<key>^(.*/)?\\.DS_Store$</key>\n\t\t<dict>\n\t\t\t<key>omit</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>2000</real>\n\t\t</dict>\n\t\t<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>\n\t\t<dict>\n\t\t\t<key>nested</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>10</real>\n\t\t</dict>\n\t\t<key>^.*</key>\n\t\t<true/>\n\t\t<key>^Info\\.plist$</key>\n\t\t<dict>\n\t\t\t<key>omit</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>20</real>\n\t\t</dict>\n\t\t<key>^PkgInfo$</key>\n\t\t<dict>\n\t\t\t<key>omit</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>20</real>\n\t\t</dict>\n\t\t<key>^Resources/</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>20</real>\n\t\t</dict>\n\t\t<key>^Resources/.*\\.lproj/</key>\n\t\t<dict>\n\t\t\t<key>optional</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>1000</real>\n\t\t</dict>\n\t\t<key>^Resources/.*\\.lproj/locversion.plist$</key>\n\t\t<dict>\n\t\t\t<key>omit</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>1100</real>\n\t\t</dict>\n\t\t<key>^Resources/Base\\.lproj/</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>1010</real>\n\t\t</dict>\n\t\t<key>^[^/]+$</key>\n\t\t<dict>\n\t\t\t<key>nested</key>\n\t\t\t<true/>\n\t\t\t<key>weight</key>\n\t\t\t<real>10</real>\n\t\t</dict>\n\t\t<key>^embedded\\.provisionprofile$</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>20</real>\n\t\t</dict>\n\t\t<key>^version\\.plist$</key>\n\t\t<dict>\n\t\t\t<key>weight</key>\n\t\t\t<real>20</real>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature/CodeResources.meta",
    "content": "fileFormatVersion: 2\nguid: 724b52b308e9a4a6d889d7bf3945a2ca\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents/_CodeSignature.meta",
    "content": "fileFormatVersion: 2\nguid: 16068f30788004029bd487756623799b\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle/Contents.meta",
    "content": "fileFormatVersion: 2\nguid: 28175da64865f4e398b3b9ddfbe97b24\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle.meta",
    "content": "fileFormatVersion: 2\nguid: 682114f7790724ab3b9410e89bbc076c\nfolderAsset: yes\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 1\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Standalone: OSXUniversal\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Mac.meta",
    "content": "fileFormatVersion: 2\nguid: 96a328019e42349aabc478b546b8605e\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityStoreKit2Bridge.swift",
    "content": "import Foundation\nimport StoreKit\n\n#if canImport(PurchaseConnector)\nimport PurchaseConnector\n\n@available(iOS 15.0, *)\n@objc\npublic class AFUnityStoreKit2Bridge: NSObject {\n    @objc\n    public static func fetchAFSDKTransactionSK2(withTransactionId transactionId: String, completion: @escaping (AFSDKTransactionSK2?) -> Void) {\n        guard let transactionIdUInt64 = UInt64(transactionId) else {\n            print(\"Invalid transaction ID format.\")\n            completion(nil)\n            return\n        }\n        Task {\n            for await result in StoreKit.Transaction.all {\n                if case .verified(let transaction) = result, transaction.id == transactionIdUInt64 {\n                    let afTransaction = AFSDKTransactionSK2(transaction: transaction)\n                    DispatchQueue.main.async {\n                        completion(afTransaction)\n                    }\n                    return\n                }\n            }\n            DispatchQueue.main.async {\n                completion(nil)\n            }\n        }\n    }\n\n    @objc\n    public static func extractSK2ProductInfo(_ products: [AFSDKProductSK2]) -> NSArray {\n        var result: [[String: Any]] = []\n\n        for product in products {\n            if let swiftProduct = Mirror(reflecting: product).children.first(where: { $0.label == \"product\" })?.value {\n                let productId = (swiftProduct as? NSObject)?.value(forKey: \"id\") as? String ?? \"\"\n                let title = (swiftProduct as? NSObject)?.value(forKey: \"displayName\") as? String ?? \"\"\n                let desc = (swiftProduct as? NSObject)?.value(forKey: \"description\") as? String ?? \"\"\n                let price = (swiftProduct as? NSObject)?.value(forKey: \"price\") as? NSDecimalNumber ?? 0\n\n                result.append([\n                    \"productIdentifier\": productId,\n                    \"localizedTitle\": title,\n                    \"localizedDescription\": desc,\n                    \"price\": price\n                ])\n            }\n        }\n\n        return result as NSArray\n    }\n    \n    @objc\n    public static func extractSK2TransactionInfo(_ transactions: [AFSDKTransactionSK2]) -> NSArray {\n        var result: [[String: Any]] = []\n\n        for txn in transactions {\n            guard let mirrorChild = Mirror(reflecting: txn).children.first(where: { $0.label == \"transaction\" }),\n                  let swiftTxn = mirrorChild.value as? StoreKit.Transaction else {\n                continue\n            }\n\n            let transactionId = \"\\(swiftTxn.id)\"\n            let date = NSNumber(value: swiftTxn.purchaseDate.timeIntervalSince1970)\n\n            result.append([\n                \"transactionIdentifier\": transactionId,\n                \"transactionState\": \"verified\", // or skip this line\n                \"transactionDate\": date\n            ])\n        }\n\n        return result as NSArray\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityStoreKit2Bridge.swift.meta",
    "content": "fileFormatVersion: 2\nguid: 5652805602a6b4273a6e527b00aea272"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityUtils.h",
    "content": "//\n//  AFUnityUtils.h\n//\n//  Created by Andrii H. and Dmitry O. on 16 Oct 2023\n//\n\n#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)\n#import <AppsFlyerLib/AppsFlyerLib.h>\n#else\n#import \"AppsFlyerLib.h\"\n#endif\n\nstatic NSString* stringFromChar(const char *str);\nstatic NSDictionary* dictionaryFromJson(const char *jsonString);\nstatic const char* stringFromdictionary(NSDictionary* dictionary);\nstatic NSArray<NSString*> *NSArrayFromCArray(int length, const char **arr);\nstatic char* getCString(const char* string);\nstatic AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator*  generator);\nstatic EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt);\nstatic AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetwork);\nstatic NSNumber *intFromNullableBool(const char *cStr);\nstatic NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult);\nstatic NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result);\n\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityUtils.h.meta",
    "content": "fileFormatVersion: 2\nguid: 4b0609ff467554f2088aee1c52bf54a2\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityUtils.mm",
    "content": "//\n//  AFUnityUtils.mm\n//  Unity-iPhone\n//\n//  Created by Jonathan Wesfield on 24/07/2019.\n//\n\n#import \"AFUnityUtils.h\"\n\nstatic NSString* stringFromChar(const char *str) {\n    return str ? [NSString stringWithUTF8String:str] : nil;\n}\n\nstatic NSDictionary* dictionaryFromJson(const char *jsonString) {\n    if(jsonString){\n        NSData *jsonData = [[NSData alloc] initWithBytes:jsonString length:strlen(jsonString)];\n        NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];\n        return dictionary;\n    }\n    \n    return nil;\n}\n\nstatic const char* stringFromdictionary(NSDictionary* dictionary) {\n    if(dictionary){\n        NSError * err;\n        NSData * jsonData = [NSJSONSerialization  dataWithJSONObject:dictionary options:0 error:&err];\n        NSString * myString = [[NSString alloc] initWithData:jsonData   encoding:NSUTF8StringEncoding];\n        return [myString UTF8String];\n    }\n\n    return nil;\n}\n\nstatic NSDictionary* dictionaryFromNSError(NSError* error) {\n    if(error){\n        NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];\n        errorDictionary[@\"code\"] = @(error.code);\n        errorDictionary[@\"localizedDescription\"] = error.localizedDescription ?: @\"\";\n        \n        // Include userInfo fields for enhanced error reporting (iOS SDK 6.17.8+)\n        if (error.userInfo[@\"error_code\"]) {\n            errorDictionary[@\"error_code\"] = error.userInfo[@\"error_code\"];\n        }\n        if (error.userInfo[@\"error_message\"]) {\n            errorDictionary[@\"error_message\"] = error.userInfo[@\"error_message\"];\n        }\n        if (error.userInfo[@\"invalid_fields\"]) {\n            errorDictionary[@\"invalid_fields\"] = error.userInfo[@\"invalid_fields\"];\n        }\n        \n        return errorDictionary;\n    }\n\n    return nil;\n}\n\n\nstatic NSArray<NSString*> *NSArrayFromCArray(int length, const char **arr) {\n    NSMutableArray<NSString *> *res = [[NSMutableArray alloc] init];\n    for(int i = 0; i < length; i++) {\n        if (arr[i]) {\n            [res addObject:[NSString stringWithUTF8String:arr[i]]];\n        }\n    }\n    \n    return res;\n}\n\nstatic char* getCString(const char* string){\n    if (string == NULL){\n        return NULL;\n    }\n    \n    char* res = (char*)malloc(strlen(string) + 1);\n    strcpy(res, string);\n    \n    return res;\n}\n\nstatic AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator*  generator) {\n    \n    NSArray* generatorKeys = @[@\"channel\", @\"customerID\", @\"campaign\", @\"referrerName\", @\"referrerImageUrl\", @\"deeplinkPath\", @\"baseDeeplink\", @\"brandDomain\"];\n    \n    NSMutableDictionary* mutableDictionary = [dictionary mutableCopy];\n    \n    [generator setChannel:[dictionary objectForKey: @\"channel\"]];\n    [generator setReferrerCustomerId:[dictionary objectForKey: @\"customerID\"]];\n    [generator setCampaign:[dictionary objectForKey: @\"campaign\"]];\n    [generator setReferrerName:[dictionary objectForKey: @\"referrerName\"]];\n    [generator setReferrerImageURL:[dictionary objectForKey: @\"referrerImageUrl\"]];\n    [generator setDeeplinkPath:[dictionary objectForKey: @\"deeplinkPath\"]];\n    [generator setBaseDeeplink:[dictionary objectForKey: @\"baseDeeplink\"]];\n    [generator setBrandDomain:[dictionary objectForKey: @\"brandDomain\"]];\n\n\n    [mutableDictionary removeObjectsForKeys:generatorKeys];\n    \n    [generator addParameters:mutableDictionary];\n    \n    return generator;\n}\n\nstatic EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt){\n    \n    EmailCryptType emailCryptType;\n    switch (emailCryptTypeInt){\n        case 1:\n            emailCryptType = EmailCryptTypeSHA256;\n            break;\n        default:\n            emailCryptType = EmailCryptTypeNone;\n            break;\n    }\n\n    return emailCryptType;\n}\n\nstatic NSNumber *intFromNullableBool(const char *cStr) {\n    if (!cStr) return nil;\n    NSString *str = [NSString stringWithUTF8String:cStr];\n\n    if ([str caseInsensitiveCompare:@\"true\"] == NSOrderedSame) {\n        return @YES;\n    } else if ([str caseInsensitiveCompare:@\"false\"] == NSOrderedSame) {\n        return @NO;\n    }\n    return nil;\n}\n\nstatic AppsFlyerAdRevenueMediationNetworkType mediationNetworkTypeFromInt(int mediationNetworkInt){\n    \n    AppsFlyerAdRevenueMediationNetworkType mediationNetworkType;\n    switch (mediationNetworkInt){\n        case 1:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob;\n            break;\n        case 2:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeIronSource;\n            break;\n        case 3:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeApplovinMax;\n            break;\n        case 4:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeFyber;\n            break;\n        case 5:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAppodeal;\n            break;\n        case 6:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeAdmost;\n            break;\n        case 7:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTopon;\n            break;\n        case 8:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeTradplus;\n            break;\n        case 9:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeYandex;\n            break;\n        case 10:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeChartBoost;\n            break;\n        case 11:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeUnity;\n            break;\n        case 12:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeToponPte;\n            break;\n        case 13:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom;\n            break;\n        case 14:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization;\n            break;\n        default:\n            mediationNetworkType = AppsFlyerAdRevenueMediationNetworkTypeCustom;\n            break;\n    }\n\n    return mediationNetworkType;\n}\n\nstatic NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult){\n    NSString* result;\n    switch (deepLinkResult){\n        case AFSDKDeepLinkResultStatusFound:\n            result = @\"FOUND\";\n            break;\n        case AFSDKDeepLinkResultStatusFailure:\n            result = @\"ERROR\";\n            break;\n        case AFSDKDeepLinkResultStatusNotFound:\n            result = @\"NOT_FOUND\";\n            break;\n        default:\n            result = @\"ERROR\";\n            break;\n    }\n    \n    return result;\n}\n\nstatic NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result){\n    NSString* res;\n    \n    if (result && result.error){\n        if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1001) {\n            res = @\"TIMEOUT\";\n       } else if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1009) {\n           res = @\"NETWORK\";\n       }\n    }\n    \n    res = @\"UNKNOWN\";\n    \n    return res;\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AFUnityUtils.mm.meta",
    "content": "fileFormatVersion: 2\nguid: 18a03931864e84d86bedcc99c440e060\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      iPhone: iOS\n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      tvOS: tvOS\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyer+AppController.m",
    "content": "//\n//  AppsFlyer+AppController.m\n//  Unity-iPhone\n//\n//  Created by Jonathan Wesfield on 24/07/2019.\n//\n\n#import <objc/runtime.h>\n#import \"UnityAppController.h\"\n#import \"AppsFlyeriOSWrapper.h\"\n#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)\n#import <AppsFlyerLib/AppsFlyerLib.h>\n#else\n#import \"AppsFlyerLib.h\"\n#endif\n\n\n@implementation UnityAppController (AppsFlyerSwizzledAppController)\n\nstatic BOOL didEnteredBackGround __unused;\nstatic IMP __original_applicationDidBecomeActive_Imp __unused;\nstatic IMP __original_applicationDidEnterBackground_Imp __unused;\nstatic IMP __original_didReceiveRemoteNotification_Imp __unused;\nstatic IMP __original_continueUserActivity_Imp __unused;\nstatic IMP __original_openUrl_Imp __unused;\n\n\n+ (void)load {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n\n#if !AFSDK_SHOULD_SWIZZLE\n\n        id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"AppsFlyerShouldSwizzle\"];\n        BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;\n        \n        if(shouldSwizzle){\n            \n            Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));\n            __original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);\n                    \n            Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));\n            __original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);\n            \n           \n            Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));\n            __original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);\n            \n           \n            Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));\n            __original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);\n            \n            if (_AppsFlyerdelegate == nil) {\n                _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n            }\n           \n            [self swizzleContinueUserActivity:[self class]];\n        }\n#elif AFSDK_SHOULD_SWIZZLE\n        Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));\n        __original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);\n                    \n        Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));\n        __original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);\n            \n           \n        Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));\n        __original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);\n            \n           \n        Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));\n        __original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);\n            \n        if (_AppsFlyerdelegate == nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n        }\n           \n        [self swizzleContinueUserActivity:[self class]];\n\n#endif\n\n\n    });\n}\n\n+(void)swizzleContinueUserActivity:(Class)class {\n    \n    SEL originalSelector = @selector(application:continueUserActivity:restorationHandler:);\n    \n    Method defaultMethod = class_getInstanceMethod(class, originalSelector);\n    Method swizzledMethod = class_getInstanceMethod(class, @selector(__swizzled_continueUserActivity));\n    \n    BOOL isMethodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));\n    \n    if (isMethodExists) {\n        __original_continueUserActivity_Imp = method_setImplementation(defaultMethod, (IMP)__swizzled_continueUserActivity);\n    } else {\n        class_replaceMethod(class, originalSelector, (IMP)__swizzled_continueUserActivity, method_getTypeEncoding(swizzledMethod));\n    }\n}\n\nBOOL __swizzled_continueUserActivity(id self, SEL _cmd, UIApplication* application, NSUserActivity* userActivity, void (^restorationHandler)(NSArray*)) {\n    NSLog(@\"swizzled continueUserActivity\");\n    [[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];\n    \n    if(__original_continueUserActivity_Imp){\n        return ((BOOL(*)(id, SEL, UIApplication*, NSUserActivity*, void (^)(NSArray*)))__original_continueUserActivity_Imp)(self, _cmd, application, userActivity, NULL);\n    }\n    \n    return YES;\n}\n\n\n\nvoid __swizzled_applicationDidBecomeActive(id self, SEL _cmd, UIApplication* launchOptions) {\n    NSLog(@\"swizzled applicationDidBecomeActive\");\n    [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];\n\n    if(didEnteredBackGround && AppsFlyeriOSWarpper.didCallStart == YES){\n        [[AppsFlyerLib shared] start];\n    }\n    \n    if(__original_applicationDidBecomeActive_Imp){\n        ((void(*)(id,SEL, UIApplication*))__original_applicationDidBecomeActive_Imp)(self, _cmd, launchOptions);\n    }\n}\n\n\nvoid __swizzled_applicationDidEnterBackground(id self, SEL _cmd, UIApplication* application) {\n    NSLog(@\"swizzled applicationDidEnterBackground\");\n    didEnteredBackGround = YES;\n    if(__original_applicationDidEnterBackground_Imp){\n        ((void(*)(id,SEL, UIApplication*))__original_applicationDidEnterBackground_Imp)(self, _cmd, application);\n    }\n}\n\n\nBOOL __swizzled_didReceiveRemoteNotification(id self, SEL _cmd, UIApplication* application, NSDictionary* userInfo,void (^UIBackgroundFetchResult)(void) ) {\n    NSLog(@\"swizzled didReceiveRemoteNotification\");\n    \n    [[AppsFlyerLib shared] handlePushNotification:userInfo];\n    \n    if(__original_didReceiveRemoteNotification_Imp){\n        return ((BOOL(*)(id, SEL, UIApplication*, NSDictionary*, int(UIBackgroundFetchResult)))__original_didReceiveRemoteNotification_Imp)(self, _cmd, application, userInfo, nil);\n    }\n    return YES;\n}\n\n\n\nBOOL __swizzled_openURL(id self, SEL _cmd, UIApplication* application, NSURL* url, NSDictionary * options) {\n    NSLog(@\"swizzled openURL\");\n    [[AppsFlyerAttribution shared] handleOpenUrl:url options:options];\n    if(__original_openUrl_Imp){\n        return ((BOOL(*)(id, SEL, UIApplication*, NSURL*, NSDictionary*))__original_openUrl_Imp)(self, _cmd, application, url, options);\n    }\n    return NO;\n}\n\n\n@end\n\n\n\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyer+AppController.m.meta",
    "content": "fileFormatVersion: 2\nguid: 6ae9e1f7daef2427588fab2fbf8d35d5\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      iPhone: iOS\n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      tvOS: tvOS\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAppController.mm",
    "content": "//\n//  AppsFlyerAppController.mm\n//  Unity-iPhone\n//\n//  Created by Jonathan Wesfield on 30/07/2019.\n//\n\n#import <Foundation/Foundation.h>\n#import \"UnityAppController.h\"\n#import \"AppDelegateListener.h\"\n#import \"AppsFlyeriOSWrapper.h\"\n#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)\n#import <AppsFlyerLib/AppsFlyerLib.h>\n#else\n#import \"AppsFlyerLib.h\"\n#endif\n#import <objc/message.h>\n\n/**\n Note if you would like to use method swizzeling see AppsFlyer+AppController.m\n If you are using swizzeling then comment out the method that is being swizzeled in AppsFlyerAppController.mm\n Only use swizzeling if there are conflicts with other plugins that needs to be resolved.\n*/\n\n\n@interface AppsFlyerAppController : UnityAppController <AppDelegateListener>\n{\n    BOOL didEnteredBackGround;\n}\n@end\n\n@implementation AppsFlyerAppController\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        \n        id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"AppsFlyerShouldSwizzle\"];\n        BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;\n        \n        if(!shouldSwizzle){\n            UnityRegisterAppDelegateListener(self);\n        }\n    }\n    return self;\n}\n\n- (void)didFinishLaunching:(NSNotification*)notification {\n    NSLog(@\"got didFinishLaunching = %@\",notification.userInfo);\n\n\n    if (_AppsFlyerdelegate == nil) {\n        _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n    }\n    [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];\n\n    if (notification.userInfo[@\"url\"]) {\n        [self onOpenURL:notification];\n    }\n}\n\n-(void)didBecomeActive:(NSNotification*)notification {\n    NSLog(@\"got didBecomeActive(out) = %@\", notification.userInfo);\n    if (didEnteredBackGround == YES && AppsFlyeriOSWarpper.didCallStart == YES) {\n        [[AppsFlyerLib shared] start];\n        didEnteredBackGround = NO;\n    }\n}\n\n- (void)didEnterBackground:(NSNotification*)notification {\n    NSLog(@\"got didEnterBackground = %@\", notification.userInfo);\n    didEnteredBackGround = YES;\n}\n\n- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {\n    [[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];\n    return YES;\n}\n\n\n- (void)onOpenURL:(NSNotification*)notification {\n    NSLog(@\"got onOpenURL = %@\", notification.userInfo);\n    NSURL *url = notification.userInfo[@\"url\"];\n    NSString *sourceApplication = notification.userInfo[@\"sourceApplication\"];\n    \n    if (sourceApplication == nil) {\n        sourceApplication = @\"\";\n    }\n    \n    if (url != nil) {\n        [[AppsFlyerAttribution shared] handleOpenUrl:url sourceApplication:sourceApplication annotation:nil];\n    }\n    \n}\n\n- (void)didReceiveRemoteNotification:(NSNotification*)notification {\n    NSLog(@\"got didReceiveRemoteNotification = %@\", notification.userInfo);\n    [[AppsFlyerLib shared] handlePushNotification:notification.userInfo];\n}\n\n@end\n\n#if !(AFSDK_SHOULD_SWIZZLE)\n\nIMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)\n\n#endif\n/**\nNote if you would not like to use IMPL_APP_CONTROLLER_SUBCLASS you can replace it with the code below.\n <code>\n +(void)load\n {\n [AppsFlyerAppController plugin];\n }\n \n // Singleton accessor.\n + (AppsFlyerAppController *)plugin\n {\n static AppsFlyerAppController *sharedInstance = nil;\n static dispatch_once_t onceToken;\n \n dispatch_once(&onceToken, ^{\n \n sharedInstance = [[AppsFlyerAppController alloc] init];\n });\n \n return sharedInstance;\n }\n</code>\n **/\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAppController.mm.meta",
    "content": "fileFormatVersion: 2\nguid: 2d1497a1493b24fecaa58bd3a7b707f9\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      iPhone: iOS\n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      tvOS: tvOS\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.h",
    "content": "//\n//  AppsFlyerAttribution.h\n//  UnityFramework\n//\n//  Created by Margot Guetta on 11/04/2021.\n//\n\n#ifndef AppsFlyerAttribution_h\n#define AppsFlyerAttribution_h\n#endif /* AppsFlyerAttribution_h */\n#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)\n#import <AppsFlyerLib/AppsFlyerLib.h>\n#else\n#import \"AppsFlyerLib.h\"\n#endif\n\n\n@interface AppsFlyerAttribution : NSObject\n@property NSUserActivity*_Nullable  userActivity;\n@property (nonatomic, copy) void (^ _Nullable restorationHandler)(NSArray *_Nullable );\n@property NSURL * _Nullable url;\n@property NSDictionary * _Nullable options;\n@property NSString* _Nullable sourceApplication;\n@property id _Nullable annotation;\n@property BOOL isBridgeReady;\n\n+ (AppsFlyerAttribution *_Nullable)shared;\n- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler;\n- (void) handleOpenUrl:(NSURL*_Nullable)url options:(NSDictionary*_Nullable) options;\n- (void) handleOpenUrl: (NSURL *_Nonnull)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation;\n\n@end\n\nstatic NSString * _Nullable const AF_BRIDGE_SET = @\"bridge is set\";\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.h.meta",
    "content": "fileFormatVersion: 2\nguid: 8544dc3b3c7bb40d397b2de568df1058\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.m",
    "content": "//\n//  NSObject+AppsFlyerAttribution.m\n//  UnityFramework\n//\n//  Created by Margot Guetta on 11/04/2021.\n//\n\n#import <Foundation/Foundation.h>\n#import \"AppsFlyerAttribution.h\"\n\n@implementation AppsFlyerAttribution\n\n+ (id)shared {\n    static AppsFlyerAttribution *shared = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        shared = [[self alloc] init];\n    });\n    return shared;\n}\n\n- (id)init {\n    if (self = [super init]) {\n        self.options = nil;\n        self.restorationHandler = nil;\n        self.url = nil;\n        self.userActivity = nil;\n        self.annotation = nil;\n        self.sourceApplication = nil;\n        self.isBridgeReady = NO;\n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(receiveBridgeReadyNotification:)\n                                                     name:AF_BRIDGE_SET\n                                                   object:nil];\n  }\n  return self;\n}\n\n- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler{\n    if(self.isBridgeReady == YES){\n        [[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler];\n    }else{\n        [AppsFlyerAttribution shared].userActivity = userActivity;\n        [AppsFlyerAttribution shared].restorationHandler = restorationHandler;\n    }\n}\n\n- (void) handleOpenUrl:(NSURL *)url options:(NSDictionary *)options{\n    if(self.isBridgeReady == YES){\n        [[AppsFlyerLib shared] handleOpenUrl:url options:options];\n    }else{\n        [AppsFlyerAttribution shared].url = url;\n        [AppsFlyerAttribution shared].options = options;\n    }\n}\n\n- (void) handleOpenUrl:(NSURL *)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{\n    if(self.isBridgeReady == YES){\n        [[AppsFlyerLib shared] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation];\n    }else{\n        [AppsFlyerAttribution shared].url = url;\n        [AppsFlyerAttribution shared].sourceApplication = sourceApplication;\n        [AppsFlyerAttribution shared].annotation = annotation;\n    }\n\n}\n\n- (void) receiveBridgeReadyNotification:(NSNotification *) notification\n{\n    NSLog (@\"AppsFlyer Debug: handle deep link\");\n    if(self.url && self.sourceApplication){\n        [[AppsFlyerLib shared] handleOpenURL:self.url sourceApplication:self.sourceApplication withAnnotation:self.annotation];\n        self.url = nil;\n        self.sourceApplication = nil;\n        self.annotation = nil;\n    }else if(self.options && self.url){\n        [[AppsFlyerLib shared] handleOpenUrl:self.url options:self.options];\n        self.options = nil;\n        self.url = nil;\n    }else if(self.userActivity){\n        [[AppsFlyerLib shared] continueUserActivity:self.userActivity restorationHandler:nil];\n        self.userActivity = nil;\n        self.restorationHandler = nil;\n    }\n}\n@end\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.m.meta",
    "content": "fileFormatVersion: 2\nguid: 1060e47d7b9e2453ba575f0b455b2bf8\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      iPhone: iOS\n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      tvOS: tvOS\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.h",
    "content": "//\n//  AppsFlyeriOSWarpper.h\n//  Unity-iPhone\n//\n//  Created by Jonathan Wesfield on 24/07/2019.\n//\n\n#import \"AFUnityUtils.mm\"\n#import \"UnityAppController.h\"\n#import \"AppsFlyerAttribution.h\"\n#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)\n#import <AppsFlyerLib/AppsFlyerLib.h>\n#else\n#import \"AppsFlyerLib.h\"\n#endif\n#if __has_include(<PurchaseConnector/PurchaseConnector.h>)\n#import <PurchaseConnector/PurchaseConnector.h>\n#else\n#import \"PurchaseConnector.h\"\n#endif\n#import <PurchaseConnector/PurchaseConnector-Swift.h>\n\n// Add StoreKit 2 support\n#if __has_include(<StoreKit/StoreKit.h>)\n#import <StoreKit/StoreKit.h>\n#endif\n\n@interface AppsFlyeriOSWarpper : NSObject <AppsFlyerLibDelegate, AppsFlyerDeepLinkDelegate, AppsFlyerPurchaseRevenueDelegate, AppsFlyerPurchaseRevenueDataSource, AppsFlyerPurchaseRevenueDataSourceStoreKit2>\n\n+ (BOOL) didCallStart;\n+ (void) setDidCallStart:(BOOL)val;\n\n// Add StoreKit 2 methods\n- (void)setStoreKitVersion:(int)storeKitVersion;\n- (void)logConsumableTransaction:(id)transaction;\n\n@end\n\n\nstatic AppsFlyeriOSWarpper *_AppsFlyerdelegate;\nstatic const int kPushNotificationSize = 32;\n\nstatic NSString* ConversionDataCallbackObject = @\"AppsFlyerObject\";\n\nstatic const char* VALIDATE_CALLBACK = \"didFinishValidateReceipt\";\nstatic const char* VALIDATE_ERROR_CALLBACK = \"didFinishValidateReceiptWithError\";\nstatic const char* GCD_CALLBACK = \"onConversionDataSuccess\";\nstatic const char* GCD_ERROR_CALLBACK = \"onConversionDataFail\";\nstatic const char* OAOA_CALLBACK = \"onAppOpenAttribution\";\nstatic const char* OAOA_ERROR_CALLBACK = \"onAppOpenAttributionFailure\";\nstatic const char* GENERATE_LINK_CALLBACK = \"onInviteLinkGenerated\";\nstatic const char* OPEN_STORE_LINK_CALLBACK = \"onOpenStoreLinkGenerated\";\nstatic const char* START_REQUEST_CALLBACK = \"requestResponseReceived\";\nstatic const char* IN_APP_RESPONSE_CALLBACK = \"inAppResponseReceived\";\nstatic const char* ON_DEEPLINKING = \"onDeepLinking\";\nstatic const char* VALIDATE_AND_LOG_V2_CALLBACK = \"onValidateAndLogComplete\";\nstatic const char* VALIDATE_AND_LOG_V2_ERROR_CALLBACK = \"onValidateAndLogFailure\";\n\n\nstatic NSString* validateObjectName = @\"\";\nstatic NSString* openStoreObjectName = @\"\";\nstatic NSString* generateInviteObjectName = @\"\";\nstatic NSString* validateAndLogObjectName = @\"\";\nstatic NSString* startRequestObjectName = @\"\";\nstatic NSString* inAppRequestObjectName = @\"\";\nstatic NSString* onDeeplinkingObjectName = @\"\";\n\nstatic const char* PURCHASE_REVENUE_VALIDATION_CALLBACK = \"didReceivePurchaseRevenueValidationInfo\";\nstatic const char* PURCHASE_REVENUE_ERROR_CALLBACK = \"didReceivePurchaseRevenueError\";\n\nstatic NSString* onPurchaseValidationObjectName = @\"\";\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.h.meta",
    "content": "fileFormatVersion: 2\nguid: 147104b04b5794eaa92b4195cc328e13\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm",
    "content": "//\n//  AppsFlyeriOSWarpper.mm\n//  Unity-iPhone\n//\n//  Created by Jonathan Wesfield on 24/07/2019.\n//\n\n#import \"AppsFlyeriOSWrapper.h\"\n#import <objc/runtime.h> \n\n#import <StoreKit/StoreKit.h>\n#import \"UnityFramework/UnityFramework-Swift.h\"\n\n#if __has_include(<PurchaseConnector/PurchaseConnector-Swift.h>)\n#import <PurchaseConnector/PurchaseConnector-Swift.h>\n#elif __has_include(\"PurchaseConnector-Swift.h\")\n#import \"PurchaseConnector-Swift.h\"\n#endif\n\n#if __has_include(<UnityFramework/UnityFramework-Swift.h>)\n#import <UnityFramework/UnityFramework-Swift.h>\n#elif __has_include(\"UnityFramework-Swift.h\")\n#import \"UnityFramework-Swift.h\"\n#endif\n\nstatic void unityCallBack(NSString* objectName, const char* method, const char* msg) {\n    if(objectName){\n        UnitySendMessage([objectName UTF8String], method, msg);\n    }\n}\n\nextern \"C\" {\n \n    const void _startSDK(bool shouldCallback, const char* objectName) {\n        [[AppsFlyerLib shared] setPluginInfoWith: AFSDKPluginUnity\n                                pluginVersion:@\"6.17.91\"\n                                additionalParams:nil];\n        startRequestObjectName = stringFromChar(objectName);\n        AppsFlyeriOSWarpper.didCallStart = YES;\n        [AppsFlyerAttribution shared].isBridgeReady = YES;\n        [[NSNotificationCenter defaultCenter] postNotificationName:AF_BRIDGE_SET object: [AppsFlyerAttribution shared]];\n        [[AppsFlyerLib shared] startWithCompletionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {\n            if(shouldCallback){\n                if (error) {\n                    NSDictionary *callbackDictionary = @{@\"statusCode\":[NSNumber numberWithLong:[error code]]};\n                    unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(callbackDictionary));\n                    return;\n                }\n                if (dictionary) {\n                    unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(dictionary));\n                    return;\n                }\n            }\n        }];\n    }\n    \n    const void _setCustomerUserID (const char* customerUserID) {\n        [[AppsFlyerLib shared] setCustomerUserID:stringFromChar(customerUserID)];\n    }\n\n    const void _setAdditionalData (const char* customData) {\n        [[AppsFlyerLib shared] setAdditionalData:dictionaryFromJson(customData)];\n    }\n\n    const void _setAppsFlyerDevKey (const char* appsFlyerDevKey) {\n        [AppsFlyerLib shared].appsFlyerDevKey = stringFromChar(appsFlyerDevKey);\n    }\n\n    const void _setAppleAppID (const char* appleAppID) {\n        [AppsFlyerLib shared].appleAppID = stringFromChar(appleAppID);\n    }\n\n    const void _setCurrencyCode (const char* currencyCode) {\n        [[AppsFlyerLib shared] setCurrencyCode:stringFromChar(currencyCode)];\n    }\n\n    const void _setDisableCollectAppleAdSupport (bool disableAdvertisingIdentifier) {\n       [AppsFlyerLib shared].disableAdvertisingIdentifier = disableAdvertisingIdentifier;\n    }\n\n    const void _setIsDebug (bool isDebug) {\n        [AppsFlyerLib shared].isDebug = isDebug;\n    }\n\n    const void _setShouldCollectDeviceName (bool shouldCollectDeviceName) {\n        [AppsFlyerLib shared].shouldCollectDeviceName = shouldCollectDeviceName;\n    }\n\n    const void _setAppInviteOneLinkID (const char*  appInviteOneLinkID) {\n        [[AppsFlyerLib shared] setAppInviteOneLink:stringFromChar(appInviteOneLinkID)];\n    }\n\n    const void _setDeepLinkTimeout (long  deepLinkTimeout) {\n        [AppsFlyerLib shared].deepLinkTimeout = deepLinkTimeout;\n    }\n\n    const void _anonymizeUser (bool anonymizeUser) {\n        [AppsFlyerLib shared].anonymizeUser = anonymizeUser;\n    }\n\n    const void _enableTCFDataCollection (bool shouldCollectTcfData) {\n       [[AppsFlyerLib shared] enableTCFDataCollection:shouldCollectTcfData];\n    }\n\n    const void _setConsentData(const char* isUserSubjectToGDPR, const char* hasConsentForDataUsage, const char* hasConsentForAdsPersonalization, const char* hasConsentForAdStorage) {\n    \n        NSNumber *gdpr = intFromNullableBool(isUserSubjectToGDPR);\n        NSNumber *dataUsage = intFromNullableBool(hasConsentForDataUsage);\n        NSNumber *adsPersonalization = intFromNullableBool(hasConsentForAdsPersonalization);\n        NSNumber *adStorage = intFromNullableBool(hasConsentForAdStorage);\n\n        AppsFlyerConsent *consentData = [[AppsFlyerConsent alloc] initWithIsUserSubjectToGDPR:gdpr\n                                                                       hasConsentForDataUsage:dataUsage\n                                                           hasConsentForAdsPersonalization:adsPersonalization\n                                                                   hasConsentForAdStorage:adStorage];\n\n        [[AppsFlyerLib shared] setConsentData:consentData];\n    }\n\n    const void _logAdRevenue(const char* monetizationNetwork, int mediationNetworkInt, const char* currencyIso4217Code, double eventRevenue, const char* additionalParameters) {\n        AppsFlyerAdRevenueMediationNetworkType mediationNetwork = mediationNetworkTypeFromInt(mediationNetworkInt);\n        NSNumber *number = [NSNumber numberWithDouble:eventRevenue];\n        AFAdRevenueData *adRevenue = [[AFAdRevenueData alloc] initWithMonetizationNetwork:stringFromChar(monetizationNetwork) mediationNetwork:mediationNetwork currencyIso4217Code:stringFromChar(currencyIso4217Code) eventRevenue:number];\n        [[AppsFlyerLib shared] logAdRevenue: adRevenue additionalParameters:dictionaryFromJson(additionalParameters)];\n    }\n\n    const void _setDisableCollectIAd (bool disableCollectASA) {\n        [AppsFlyerLib shared].disableCollectASA = disableCollectASA;\n    }\n    \n    const void _setUseReceiptValidationSandbox (bool useReceiptValidationSandbox) {\n        [AppsFlyerLib shared].useReceiptValidationSandbox = useReceiptValidationSandbox;\n    }\n    \n    const void _setUseUninstallSandbox (bool useUninstallSandbox) {\n        [AppsFlyerLib shared].useUninstallSandbox = useUninstallSandbox;\n    }\n\n    const void _setResolveDeepLinkURLs (int length, const char **resolveDeepLinkURLs) {\n        if(length > 0 && resolveDeepLinkURLs) {\n            [[AppsFlyerLib shared] setResolveDeepLinkURLs:NSArrayFromCArray(length, resolveDeepLinkURLs)];\n        }\n    }\n\n    const void _setOneLinkCustomDomains (int length, const char **oneLinkCustomDomains) {\n        if(length > 0 && oneLinkCustomDomains) {\n            [[AppsFlyerLib shared] setOneLinkCustomDomains:NSArrayFromCArray(length, oneLinkCustomDomains)];\n        }\n    }\n\n    const void _afSendEvent (const char* eventName, const char* eventValues, bool shouldCallback, const char* objectName) {\n        inAppRequestObjectName = stringFromChar(objectName);\n        [[AppsFlyerLib shared] logEventWithEventName:stringFromChar(eventName) eventValues:dictionaryFromJson(eventValues) completionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {\n                if(shouldCallback){\n                    if (error) {\n                        NSDictionary *callbackDictionary = @{@\"statusCode\":[NSNumber numberWithLong:[error code]]};\n                        unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(callbackDictionary));\n                        return;\n                    }\n                    if (dictionary) {\n                        unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(dictionary));\n                        return;\n                    }\n                }\n        }];\n    }\n\n    const void _recordLocation (double longitude, double latitude) {\n        [[AppsFlyerLib shared] logLocation:longitude latitude:latitude];\n    }\n\n    const char* _getAppsFlyerId () {\n        return getCString([[[AppsFlyerLib shared] getAppsFlyerUID] UTF8String]);\n    }\n\n    const void _registerUninstall (unsigned char* deviceToken) {\n        if(deviceToken){\n            NSData* tokenData = [NSData dataWithBytes:(const void *)deviceToken length:sizeof(unsigned char)*kPushNotificationSize];\n            [[AppsFlyerLib shared] registerUninstall:tokenData];\n        }\n    }\n\n    const void _handlePushNotification (const char* pushPayload) {\n        [[AppsFlyerLib shared] handlePushNotification:dictionaryFromJson(pushPayload)];\n    }\n\n    const char* _getSDKVersion () {\n        return getCString([[[AppsFlyerLib shared] getSDKVersion] UTF8String]);\n    }\n\n    const void _setHost (const char* host, const char* hostPrefix) {\n        [[AppsFlyerLib shared] setHost:stringFromChar(host) withHostPrefix:stringFromChar(hostPrefix)];\n    }\n\n    const void _setMinTimeBetweenSessions (int minTimeBetweenSessions) {\n        [AppsFlyerLib shared].minTimeBetweenSessions = minTimeBetweenSessions;\n    }\n\n    const void _stopSDK (bool isStopped) {\n        [AppsFlyerLib shared].isStopped = isStopped;\n    }\n\n    const BOOL _isSDKStopped () {\n        return [AppsFlyerLib shared].isStopped;\n    }\n\n    const void _handleOpenUrl(const char *url, const char *sourceApplication, const char *annotation) {\n        [[AppsFlyerLib shared] handleOpenURL:[NSURL URLWithString:stringFromChar(url)] sourceApplication:stringFromChar(sourceApplication) withAnnotation:stringFromChar(annotation)];    }\n\n    const void _recordCrossPromoteImpression (const char* appID, const char* campaign, const char* parameters) {\n        [AppsFlyerCrossPromotionHelper logCrossPromoteImpression:stringFromChar(appID) campaign:stringFromChar(campaign) parameters:dictionaryFromJson(parameters)];    }\n    \n    const void _attributeAndOpenStore (const char* appID, const char* campaign, const char* parameters, const char* objectName) {\n\n        openStoreObjectName = stringFromChar(objectName);\n\n        [AppsFlyerCrossPromotionHelper\n         logAndOpenStore:stringFromChar(appID)\n         campaign:stringFromChar(campaign)\n         parameters:dictionaryFromJson(parameters)\n         openStore:^(NSURLSession * _Nonnull urlSession, NSURL * _Nonnull clickURL) {\n            unityCallBack(openStoreObjectName, OPEN_STORE_LINK_CALLBACK, [clickURL.absoluteString UTF8String]);\n        }];\n    }\n    \n    const void _generateUserInviteLink (const char* parameters, const char* objectName) {\n\n        generateInviteObjectName = stringFromChar(objectName);\n\n        [AppsFlyerShareInviteHelper generateInviteUrlWithLinkGenerator:^AppsFlyerLinkGenerator * _Nonnull(AppsFlyerLinkGenerator * _Nonnull generator) {\n            return generatorFromDictionary(dictionaryFromJson(parameters), generator);\n        } completionHandler:^(NSURL * _Nullable url) {\n            unityCallBack(generateInviteObjectName, GENERATE_LINK_CALLBACK, [url.absoluteString UTF8String]);\n        }];\n    }\n    \n    const void _recordInvite (const char* channel, const char* parameters) {\n        [AppsFlyerShareInviteHelper logInvite:stringFromChar(channel) parameters:dictionaryFromJson(parameters)];\n    }\n    \n    const void _setUserEmails (int emailCryptTypeInt , int length, const char **userEmails) {\n        if(length > 0 && userEmails) {\n            [[AppsFlyerLib shared] setUserEmails:NSArrayFromCArray(length, userEmails) withCryptType:emailCryptTypeFromInt(emailCryptTypeInt)];\n        }\n    }\n\n    const void _setPhoneNumber (const char* phoneNumber) {\n        [[AppsFlyerLib shared] setPhoneNumber:stringFromChar(phoneNumber)];\n    }\n\n    const void _setSharingFilterForAllPartners () {\n        [[AppsFlyerLib shared] setSharingFilterForAllPartners];\n    }\n\n    const void _setSharingFilter (int length, const char **partners) {\n        if(length > 0 && partners) {\n            [[AppsFlyerLib shared] setSharingFilter:NSArrayFromCArray(length, partners)];\n        }\n    }\n\n    const void _setSharingFilterForPartners (int length, const char **partners) {\n        if(length > 0 && partners) {\n            [[AppsFlyerLib shared] setSharingFilterForPartners:NSArrayFromCArray(length, partners)];\n        } else {\n            [[AppsFlyerLib shared] setSharingFilterForPartners:nil];\n        }\n    }\n    \n    const void _validateAndSendInAppPurchase (const char* productIdentifier, const char* price, const char* currency, const char* transactionId, const char* additionalParameters, const char* objectName) {\n\n        validateObjectName = stringFromChar(objectName);\n\n        [[AppsFlyerLib shared]\n         validateAndLogInAppPurchase:stringFromChar(productIdentifier)\n         price:stringFromChar(price)\n         currency:stringFromChar(currency)\n         transactionId:stringFromChar(transactionId)\n         additionalParameters:dictionaryFromJson(additionalParameters)\n         success:^(NSDictionary *result){\n                 unityCallBack(validateObjectName, VALIDATE_CALLBACK, stringFromdictionary(result));\n         } failure:^(NSError *error, id response) {\n            if(response && [response isKindOfClass:[NSDictionary class]]) {\n                 NSDictionary* value = (NSDictionary*)response;\n                 unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, stringFromdictionary(value));\n             } else {\n                 unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, error ? [[error localizedDescription] UTF8String] : \"error\");\n             }\n         }];\n    }\n\n    const void _validateAndSendInAppPurchaseV2 (const char* product, const char* transactionId, int purchaseType, const char* purchaseAdditionalDetails, const char* objectName) {\n\n        validateAndLogObjectName = stringFromChar(objectName);\n        AFSDKPurchaseDetails *details = [[AFSDKPurchaseDetails alloc] initWithProductId:stringFromChar(product) transactionId:stringFromChar(transactionId) purchaseType:(AFSDKPurchaseType)purchaseType];\n\n        [[AppsFlyerLib shared]\n         validateAndLogInAppPurchase:details\n         purchaseAdditionalDetails:dictionaryFromJson(purchaseAdditionalDetails)\n         completion:^(NSDictionary * _Nullable response, NSError * _Nullable error) {\n            if (error) {\n                unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_ERROR_CALLBACK, stringFromdictionary(dictionaryFromNSError(error)));\n            } else {\n                unityCallBack(validateAndLogObjectName, VALIDATE_AND_LOG_V2_CALLBACK, stringFromdictionary(response));\n            }\n        }];\n         \n    }\n    \n    const void _getConversionData(const char* objectName) {\n        if (_AppsFlyerdelegate == nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n        }\n        ConversionDataCallbackObject = stringFromChar(objectName);\n        [[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];\n    }\n\n    const void _waitForATTUserAuthorizationWithTimeoutInterval (int timeoutInterval) {\n       [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval];\n    }\n\n    const void _disableSKAdNetwork (bool isDisabled) {\n        [AppsFlyerLib shared].disableSKAdNetwork = isDisabled;\n    }\n\n    const void _addPushNotificationDeepLinkPath (int length, const char **paths) {\n        if(length > 0 && paths) {\n            [[AppsFlyerLib shared] addPushNotificationDeepLinkPath:NSArrayFromCArray(length, paths)];\n        }\n    }\n\n    const void _subscribeForDeepLink (const char* objectName) {\n\n        onDeeplinkingObjectName = stringFromChar(objectName);\n        \n        if (_AppsFlyerdelegate == nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n        }\n        [[AppsFlyerLib shared] setDeepLinkDelegate:_AppsFlyerdelegate];\n    }\n\n    const void _setCurrentDeviceLanguage(const char* language) {\n        [[AppsFlyerLib shared] setCurrentDeviceLanguage:stringFromChar(language)];\n    }\n\n    const void _setPartnerData(const char* partnerId, const char* partnerInfo) {\n        [[AppsFlyerLib shared] setPartnerDataWithPartnerId: stringFromChar(partnerId) partnerInfo:dictionaryFromJson(partnerInfo)];\n    }\n\n    const void _disableIDFVCollection(bool isDisabled) {\n        [AppsFlyerLib shared].disableIDFVCollection = isDisabled;\n    }\n\n    // Purchase connector\n    const void _startObservingTransactions() {\n        [[PurchaseConnector shared] startObservingTransactions];\n    }\n\n    const void _stopObservingTransactions() {\n        [[PurchaseConnector shared] stopObservingTransactions];\n    }\n\n    const void _setIsSandbox(bool isSandBox) {\n        [[PurchaseConnector shared] setIsSandbox:isSandBox];\n    }\n\n    const void _setPurchaseRevenueDelegate() {\n        if (_AppsFlyerdelegate== nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n               }\n        [[PurchaseConnector shared] setPurchaseRevenueDelegate:_AppsFlyerdelegate];\n    }\n\n    const void _setAutoLogPurchaseRevenue(int option) {\n           [[PurchaseConnector shared] setAutoLogPurchaseRevenue:option];\n\n    }\n\n    const void _initPurchaseConnector(const char* objectName) {\n        if (_AppsFlyerdelegate == nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n        }\n        onPurchaseValidationObjectName = stringFromChar(objectName);\n    }\n\n    const void _setPurchaseRevenueDataSource(const char* objectName) {\n        if (_AppsFlyerdelegate == nil) {\n            _AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];\n        }\n\n        if (strstr(objectName, \"StoreKit2\") != NULL) {\n            \n            // Force protocol conformance\n            Protocol *sk2Protocol = @protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2);\n            class_addProtocol([_AppsFlyerdelegate class], sk2Protocol);\n            \n            if (![_AppsFlyerdelegate conformsToProtocol:@protocol(AppsFlyerPurchaseRevenueDataSourceStoreKit2)]) {\n                NSLog(@\"[AppsFlyer] Warning: SK2 protocol not conformed!\");\n            }\n        }\n        \n        [PurchaseConnector shared].purchaseRevenueDataSource = _AppsFlyerdelegate;\n    }\n\n    const void _setStoreKitVersion(int storeKitVersion) {\n        [[PurchaseConnector shared] setStoreKitVersion:(AFSDKStoreKitVersion)storeKitVersion];\n    }\n\n    const void _logConsumableTransaction(const char* transactionId) {\n        if (@available(iOS 15.0, *)) {\n            NSString *transactionIdStr = [NSString stringWithUTF8String:transactionId];\n            [AFUnityStoreKit2Bridge fetchAFSDKTransactionSK2WithTransactionId:transactionIdStr completion:^(AFSDKTransactionSK2 *afTransaction) {\n                if (afTransaction) {\n                    [[PurchaseConnector shared] logConsumableTransaction:afTransaction];\n                } else {\n                    NSLog(@\"No AFSDKTransactionSK2 found for id %@\", transactionIdStr);\n                }\n            }];\n        }\n    }\n\n    #ifdef __cplusplus\n    extern \"C\" {\n    #endif\n\n    typedef const char *(*UnityPurchaseCallback)(const char *, const char *);\n\n    UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallback = NULL;\n    UnityPurchaseCallback UnityPurchasesGetAdditionalParamsCallbackSK2 = NULL;\n\n    __attribute__((visibility(\"default\")))\n    void RegisterUnityPurchaseRevenueParamsCallback(UnityPurchaseCallback callback) {\n        UnityPurchasesGetAdditionalParamsCallback = callback;\n    }\n\n    __attribute__((visibility(\"default\")))\n    void RegisterUnityPurchaseRevenueParamsCallbackSK2(UnityPurchaseCallback callback) {\n        UnityPurchasesGetAdditionalParamsCallbackSK2 = callback;\n    }\n\n\n    #ifdef __cplusplus\n    }\n    #endif\n}\n\n@implementation AppsFlyeriOSWarpper\n\nstatic BOOL didCallStart;\n+ (BOOL) didCallStart\n{ @synchronized(self) { return didCallStart; } }\n+ (void) setDidCallStart:(BOOL)val\n{ @synchronized(self) { didCallStart = val; } }\n\n- (void)onConversionDataSuccess:(NSDictionary *)installData {\n    unityCallBack(ConversionDataCallbackObject, GCD_CALLBACK, stringFromdictionary(installData));\n}\n\n- (void)onConversionDataFail:(NSError *)error {\n    unityCallBack(ConversionDataCallbackObject, GCD_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);\n}\n\n- (void)onAppOpenAttribution:(NSDictionary *)attributionData {\n    unityCallBack(ConversionDataCallbackObject, OAOA_CALLBACK, stringFromdictionary(attributionData));\n}\n\n- (void)onAppOpenAttributionFailure:(NSError *)error {\n    unityCallBack(ConversionDataCallbackObject, OAOA_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);\n}\n\n- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result{\n    \n    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];\n    \n    [dict setValue:stringFromDeepLinkResultError(result) forKey:@\"error\"];\n    [dict setValue:stringFromDeepLinkResultStatus(result.status) forKey:@\"status\"];\n    \n    if(result && result.deepLink){\n        [dict setValue:result.deepLink.description forKey:@\"deepLink\"];\n        [dict setValue:@(result.deepLink.isDeferred) forKey:@\"is_deferred\"];\n    }\n    \n    unityCallBack(onDeeplinkingObjectName, ON_DEEPLINKING, stringFromdictionary(dict));\n}\n\n// Purchase Connector\n- (void)didReceivePurchaseRevenueValidationInfo:(NSDictionary *)validationInfo error:(NSError *)error {\n    if (error != nil) {\n        unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);\n    } else {\n        unityCallBack(onPurchaseValidationObjectName, PURCHASE_REVENUE_VALIDATION_CALLBACK, stringFromdictionary(validationInfo));\n    }\n}\n\n- (NSDictionary *)purchaseRevenueAdditionalParametersForProducts:(NSSet<SKProduct *> *)products\n                                                     transactions:(NSSet<SKPaymentTransaction *> *)transactions {\n\n    NSMutableArray *productsArray = [NSMutableArray array];\n    for (SKProduct *product in products) {\n        [productsArray addObject:@{\n            @\"productIdentifier\": product.productIdentifier ?: @\"\",\n            @\"localizedTitle\": product.localizedTitle ?: @\"\",\n            @\"localizedDescription\": product.localizedDescription ?: @\"\",\n            @\"price\": [product.price stringValue] ?: @\"\"\n        }];\n    }\n\n    NSMutableArray *transactionsArray = [NSMutableArray array];\n    for (SKPaymentTransaction *txn in transactions) {\n        [transactionsArray addObject:@{\n            @\"transactionIdentifier\": txn.transactionIdentifier ?: @\"\",\n            @\"transactionState\": @(txn.transactionState),\n            @\"transactionDate\": txn.transactionDate ? [@(txn.transactionDate.timeIntervalSince1970) stringValue] : @\"\"\n        }];\n    }\n\n    NSDictionary *input = @{\n        @\"products\": productsArray,\n        @\"transactions\": transactionsArray\n    };\n\n    NSError *error = nil;\n    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error];\n    if (error || !jsonData) {\n        NSLog(@\"[AppsFlyer] Failed to serialize Unity purchase data: %@\", error);\n        return @{};\n    }\n\n    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];\n    if (!jsonString || !UnityPurchasesGetAdditionalParamsCallback) {\n        NSLog(@\"[AppsFlyer] Unity callback not registered\");\n        return @{};\n    }\n\n    const char *resultCStr = UnityPurchasesGetAdditionalParamsCallback([jsonString UTF8String], \"\");\n    if (!resultCStr) {\n        NSLog(@\"[AppsFlyer] Unity callback returned null\");\n        return @{};\n    }\n\n    NSString *resultJson = [NSString stringWithUTF8String:resultCStr];\n    NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding];\n    NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error];\n\n    if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) {\n        NSLog(@\"[AppsFlyer] Failed to parse Unity response: %@\", error);\n        return @{};\n    }\n\n    return parsedResult;\n}\n\n#pragma mark - AppsFlyerPurchaseRevenueDataSourceStoreKit2\n- (NSDictionary *)purchaseRevenueAdditionalParametersStoreKit2ForProducts:(NSSet<AFSDKProductSK2 *> *)products transactions:(NSSet<AFSDKTransactionSK2 *> *)transactions {\n    if (@available(iOS 15.0, *)) {\n        NSArray *productInfoArray = [AFUnityStoreKit2Bridge extractSK2ProductInfo:[products allObjects]];\n        NSArray *transactionInfoArray = [AFUnityStoreKit2Bridge extractSK2TransactionInfo:[transactions allObjects]];\n\n        NSDictionary *input = @{\n            @\"products\": productInfoArray,\n            @\"transactions\": transactionInfoArray\n        };\n\n        if (UnityPurchasesGetAdditionalParamsCallbackSK2) {\n            NSError *error = nil;\n            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:input options:0 error:&error];\n            if (error || !jsonData) {\n                NSLog(@\"[AppsFlyer] Failed to serialize Unity purchase data: %@\", error);\n                return @{};\n            }\n\n            NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];\n            \n            const char *resultCStr = UnityPurchasesGetAdditionalParamsCallbackSK2([jsonString UTF8String], \"\");\n            if (!resultCStr) {\n                NSLog(@\"[AppsFlyer] Unity callback returned null\");\n                return @{};\n            }\n\n            NSString *resultJson = [NSString stringWithUTF8String:resultCStr];\n            \n            NSData *resultData = [resultJson dataUsingEncoding:NSUTF8StringEncoding];\n            NSDictionary *parsedResult = [NSJSONSerialization JSONObjectWithData:resultData options:0 error:&error];\n\n            if (error || ![parsedResult isKindOfClass:[NSDictionary class]]) {\n                NSLog(@\"[AppsFlyer] Failed to parse Unity response: %@\", error);\n                return @{};\n            }\n\n            return parsedResult;\n        } else {\n            NSLog(@\"[AppsFlyer] SK2 - Unity callback is NOT registered\");\n        }\n    } else {\n        NSLog(@\"[AppsFlyer] SK2 - iOS version not supported\");\n    }\n    return @{};\n}\n\n@end\n\n\n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm.meta",
    "content": "fileFormatVersion: 2\nguid: 2bff3788f3d8747fe9679bd3818e1d76\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      iPhone: iOS\n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      tvOS: tvOS\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins/iOS.meta",
    "content": "fileFormatVersion: 2\nguid: d8325c12a80ff4323b82e2833a8fc287\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Plugins.meta",
    "content": "fileFormatVersion: 2\nguid: 66297743248ab4e47abdc371a59f1111\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/ProductPurchase.cs",
    "content": "#nullable enable\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing System;\nusing UnityEngine;\n\n[System.Serializable]\npublic class InAppPurchaseValidationResult : EventArgs\n{\n    public bool success;\n    public ProductPurchase? productPurchase;\n    public ValidationFailureData? failureData;\n    public string? token;\n}\n\n[System.Serializable]\npublic class ProductPurchase\n{\n    public string? kind;\n    public string? purchaseTimeMillis;\n    public int purchaseState;\n    public int consumptionState;\n    public string? developerPayload;\n    public string? orderId;\n    public int purchaseType;\n    public int acknowledgementState;\n    public string? purchaseToken;\n    public string? productId;\n    public int quantity;\n    public string? obfuscatedExternalAccountId;\n    public string? obfuscatedExternalProfil;\n    public string? regionCode;\n}\n\n[System.Serializable]\npublic class ValidationFailureData\n{\n    public int status;\n    public string? description;\n}\n\n[System.Serializable]\npublic class SubscriptionValidationResult\n{\n    public bool success;\n    public SubscriptionPurchase? subscriptionPurchase;\n    public ValidationFailureData? failureData;\n    public string? token;\n}\n\n[System.Serializable]\npublic class SubscriptionPurchase\n{\n    public string? acknowledgementState;\n    public CanceledStateContext? canceledStateContext;\n    public ExternalAccountIdentifiers? externalAccountIdentifiers;\n    public string? kind;\n    public string? latestOrderId;\n    public List<SubscriptionPurchaseLineItem>? lineItems;\n    public string? linkedPurchaseToken;\n    public PausedStateContext? pausedStateContext;\n    public string? regionCode;\n    public string? startTime;\n    public SubscribeWithGoogleInfo? subscribeWithGoogleInfo;\n    public string? subscriptionState;\n    public TestPurchase? testPurchase;\n}\n\n[System.Serializable]\npublic class CanceledStateContext\n{\n    public DeveloperInitiatedCancellation? developerInitiatedCancellation;\n    public ReplacementCancellation? replacementCancellation;\n    public SystemInitiatedCancellation? systemInitiatedCancellation;\n    public UserInitiatedCancellation? userInitiatedCancellation;\n\n}\n\n[System.Serializable]\npublic class ExternalAccountIdentifiers\n{\n    public string? externalAccountId;\n    public string? obfuscatedExternalAccountId;\n    public string? obfuscatedExternalProfileId;\n}\n\n[System.Serializable]\npublic class SubscriptionPurchaseLineItem\n{\n    public AutoRenewingPlan? autoRenewingPlan;\n    public DeferredItemReplacement? deferredItemReplacement;\n    public string? expiryTime;\n    public OfferDetails? offerDetails;\n    public PrepaidPlan? prepaidPlan;\n    public string? productId;\n}\n\n[System.Serializable]\npublic class PausedStateContext\n{\n    public string? autoResumeTime;\n}\n\n[System.Serializable]\npublic class SubscribeWithGoogleInfo\n{\n    public string? emailAddress;\n    public string? familyName;\n    public string? givenName;\n    public string? profileId;\n    public string? profileName;\n}\n\n[System.Serializable]\npublic class TestPurchase{}\n\n[System.Serializable]\npublic class DeveloperInitiatedCancellation{}\n\n[System.Serializable]\npublic class ReplacementCancellation{}\n\n[System.Serializable]\npublic class SystemInitiatedCancellation{}\n\n[System.Serializable]\npublic class UserInitiatedCancellation\n{\n    public CancelSurveyResult? cancelSurveyResult;\n    public string? cancelTime;\n}\n\n[System.Serializable]\npublic class AutoRenewingPlan\n{\n    public string? autoRenewEnabled;\n    public SubscriptionItemPriceChangeDetails? priceChangeDetails;\n}\n\n[System.Serializable]\npublic class DeferredItemReplacement\n{\n    public string? productId;\n}\n\n[System.Serializable]\npublic class OfferDetails\n{\n    public List<string>? offerTags;\n    public string? basePlanId;\n    public string? offerId;\n}\n\n[System.Serializable]\npublic class PrepaidPlan\n{\n    public string? allowExtendAfterTime;\n}\n\n[System.Serializable]\npublic class CancelSurveyResult\n{\n    public string? reason;\n    public string? reasonUserInput;\n}\n\n[System.Serializable]\npublic class SubscriptionItemPriceChangeDetails\n{\n    public string? expectedNewPriceChargeTime;\n    public Money? newPrice;\n    public string? priceChangeMode;\n    public string? priceChangeState;\n}\n\n[System.Serializable]\n public class Money\n {\n    public string? currencyCode;\n    public long nanos;\n    public long units;\n }\n   "
  },
  {
    "path": "Assets/AppsFlyer/ProductPurchase.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 9a1435104a69d4c8ebcc6f237cc29a54\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/Castle.Core.dll.meta",
    "content": "fileFormatVersion: 2\nguid: 7b5b4579db85b4cfd8395bfb19aa309e\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 0\n      settings:\n        CPU: AnyCPU\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/NSubstitute.dll.meta",
    "content": "fileFormatVersion: 2\nguid: 642cf65ed2573419bab7e7d44fc73181\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 0\n      settings:\n        CPU: AnyCPU\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/System.Runtime.CompilerServices.Unsafe.dll.meta",
    "content": "fileFormatVersion: 2\nguid: 3a5ccbd864ba94a9a9ba47895ff14922\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 0\n      settings:\n        CPU: AnyCPU\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/System.Threading.Tasks.Extensions.dll.meta",
    "content": "fileFormatVersion: 2\nguid: ee45ae2608f3c44d08fc6e21a94d133f\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 1\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 0\n      settings:\n        CPU: AnyCPU\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/Tests.asmdef",
    "content": "{\n    \"name\": \"Tests\",\n    \"references\": [\n        \"UnityEngine.TestRunner\",\n        \"UnityEditor.TestRunner\",\n        \"AppsFlyer\"\n    ],\n    \"includePlatforms\": [],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": true,\n    \"precompiledReferences\": [\n        \"nunit.framework.dll\",\n        \"NSubstitute.dll\",\n        \"Castle.Core.dll\",\n        \"System.Threading.Tasks.Extensions.dll\"\n    ],\n    \"autoReferenced\": false,\n    \"defineConstraints\": [\n        \"UNITY_INCLUDE_TESTS\"\n    ],\n    \"versionDefines\": [],\n    \"noEngineReferences\": false\n}"
  },
  {
    "path": "Assets/AppsFlyer/Tests/Tests.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: 1f155a0e4c9ab48eeb4b54b2dc0aeba7\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/Tests_Suite.cs",
    "content": "﻿using System.Collections.Generic;\nusing NUnit.Framework;\nusing UnityEngine;\nusing NSubstitute;\n\nnamespace AppsFlyerSDK.Tests\n{\n    public class AppsFlyerSDKTests\n    {\n        private IAppsFlyerNativeBridge mock;\n\n        [SetUp]\n        public void SetUp()\n        {\n            mock = Substitute.For<IAppsFlyerNativeBridge>();\n            AppsFlyer.instance = mock;\n        }\n\n        #region SDK Initialization\n        [Test]\n        public void StartSDK_ShouldCallBridge()\n        {\n            AppsFlyer.startSDK();\n            mock.Received().startSDK(Arg.Any<bool>(), Arg.Any<string>());\n        }\n\n        [Test]\n        public void StopSDK_True_ShouldCallBridge()\n        {\n            AppsFlyer.stopSDK(true);\n            mock.Received().stopSDK(true);\n        }\n\n        [Test]\n        public void StopSDK_False_ShouldCallBridge()\n        {\n            AppsFlyer.stopSDK(false);\n            mock.Received().stopSDK(false);\n        }\n\n        [Test]\n        public void IsSDKStopped_ShouldCallBridge()\n        {\n            _ = AppsFlyer.isSDKStopped();\n            mock.Received().isSDKStopped();\n        }\n        #endregion\n\n        #region Event Sending\n        [Test]\n        public void SendEvent_WithParams_ShouldCallBridge()\n        {\n            var eventParams = new Dictionary<string, string> { { \"key\", \"value\" } };\n            AppsFlyer.sendEvent(\"testevent\", eventParams);\n            mock.Received().sendEvent(\"testevent\", eventParams, false, null);\n        }\n\n        [Test]\n        public void SendEvent_NullParams_ShouldCallBridge()\n        {\n            AppsFlyer.sendEvent(\"testevent\", null);\n            mock.Received().sendEvent(\"testevent\", null, false, null);\n        }\n        #endregion\n\n        #region Identity and Configuration\n        [Test]\n        public void SetCustomerUserId_ShouldCallBridge()\n        {\n            AppsFlyer.setCustomerUserId(\"user123\");\n            mock.Received().setCustomerUserId(\"user123\");\n        }\n\n        [Test]\n        public void SetAppInviteOneLinkID_ShouldCallBridge()\n        {\n            AppsFlyer.setAppInviteOneLinkID(\"2f36\");\n            mock.Received().setAppInviteOneLinkID(\"2f36\");\n        }\n\n        [Test]\n        public void SetAdditionalData_ShouldCallBridge()\n        {\n            var customData = new Dictionary<string, string> { { \"test\", \"test\" } };\n            AppsFlyer.setAdditionalData(customData);\n            mock.Received().setAdditionalData(customData);\n        }\n\n        [Test]\n        public void SetResolveDeepLinkURLs_ShouldCallBridge()\n        {\n            AppsFlyer.setResolveDeepLinkURLs(\"url1\", \"url2\");\n            mock.Received().setResolveDeepLinkURLs(\"url1\", \"url2\");\n        }\n\n        [Test]\n        public void SetCurrencyCode_ShouldCallBridge()\n        {\n            AppsFlyer.setCurrencyCode(\"USD\");\n            mock.Received().setCurrencyCode(\"USD\");\n        }\n\n        [Test]\n        public void SetMinTimeBetweenSessions_ShouldCallBridge()\n        {\n            AppsFlyer.setMinTimeBetweenSessions(3);\n            mock.Received().setMinTimeBetweenSessions(3);\n        }\n\n        [Test]\n        public void SetHost_ShouldCallBridge()\n        {\n            AppsFlyer.setHost(\"prefix\", \"name\");\n            mock.Received().setHost(\"prefix\", \"name\");\n\n        }\n\n        [Test]\n        public void SetPhoneNumber_ShouldCallBridge()\n        {\n            AppsFlyer.setPhoneNumber(\"002\");\n            mock.Received().setPhoneNumber(\"002\");\n        }\n\n\n        [Test]\n        [System.Obsolete]\n        public void SetSharingFilterForAllPartners_ShouldCallBridge()\n        {\n            AppsFlyer.setSharingFilterForAllPartners();\n            mock.Received().setSharingFilterForAllPartners();\n        }\n\n        [Test]\n        [System.Obsolete]\n        public void SetSharingFilter_ShouldCallBridge()\n        {\n            AppsFlyer.setSharingFilter(\"filter1\", \"filter2\");\n            mock.Received().setSharingFilter(\"filter1\", \"filter2\");\n\n        }\n\n        [Test]\n        public void SetConsentData_ShouldCallBridge_WhenInstanceIsNotNull()\n        {\n            var consent = new AppsFlyerConsent(true);\n            AppsFlyer.setConsentData(consent);\n\n            mock.Received().setConsentData(consent);\n        }\n\n        [Test]\n        public void SetConsentData_ShouldNotThrow_WhenInstanceIsNull()\n        {\n            AppsFlyer.instance = null;\n\n            var consent = new AppsFlyerConsent();\n            Assert.DoesNotThrow(() => AppsFlyer.setConsentData(consent));\n        }\n        #endregion\n\n        #region Location and Privacy\n        [Test]\n        public void RecordLocation_ShouldCallBridge()\n        {\n            AppsFlyer.recordLocation(1.23, 4.56);\n            mock.Received().recordLocation(1.23, 4.56);\n        }\n\n        [Test]\n        public void AnonymizeUser_True_ShouldCallBridge()\n        {\n            AppsFlyer.anonymizeUser(true);\n            mock.Received().anonymizeUser(true);\n        }\n\n        [Test]\n        public void AnonymizeUser_False_ShouldCallBridge()\n        {\n            AppsFlyer.anonymizeUser(false);\n            mock.Received().anonymizeUser(false);\n        }\n        #endregion\n\n        #region Utility\n        [Test]\n        public void GetAppsFlyerId_ShouldCallBridge()\n        {\n            AppsFlyer.getAppsFlyerId();\n            mock.Received().getAppsFlyerId();\n        }\n\n        [Test]\n        public void GetConversionData_ShouldCallBridge()\n        {\n            AppsFlyer.getConversionData(\"ObjectName\");\n            mock.Received().getConversionData(\"ObjectName\");\n        }\n\n        [Test]\n        public void GenerateUserInviteLink_ShouldCallBridge()\n        {\n            AppsFlyer.generateUserInviteLink(new Dictionary<string, string>(), new MonoBehaviour());\n            mock.Received().generateUserInviteLink(Arg.Any<Dictionary<string, string>>(), Arg.Any<MonoBehaviour>());\n        }\n        #endregion\n\n        #region Cross Promotion & Store\n        [Test]\n        public void AttributeAndOpenStore_WithParams_ShouldCallBridge()\n        {\n            Dictionary<string, string> parameters = new Dictionary<string, string>();\n            parameters.Add(\"af_sub1\", \"val\");\n            parameters.Add(\"custom_param\", \"val2\");\n            AppsFlyer.attributeAndOpenStore(\"appid\", \"campaign\", parameters, new MonoBehaviour());\n            mock.Received().attributeAndOpenStore(\"appid\", \"campaign\", parameters, Arg.Any<MonoBehaviour>());\n        }\n\n        [Test]\n        public void AttributeAndOpenStore_NullParams_ShouldCallBridge()\n        {\n            AppsFlyer.attributeAndOpenStore(\"appid\", \"campaign\", null, new MonoBehaviour());\n            mock.Received().attributeAndOpenStore(\"appid\", \"campaign\", null, Arg.Any<MonoBehaviour>());\n        }\n\n        [Test]\n        public void RecordCrossPromoteImpression_WithParams_ShouldCallBridge()\n        {\n            Dictionary<string, string> parameters = new Dictionary<string, string>();\n            parameters.Add(\"af_sub1\", \"val\");\n            parameters.Add(\"custom_param\", \"val2\");\n            AppsFlyer.recordCrossPromoteImpression(\"appid\", \"campaign\", parameters);\n            mock.Received().recordCrossPromoteImpression(\"appid\", \"campaign\", parameters);\n        }\n\n\n\n        [Test]\n        public void RecordCrossPromoteImpression_WithoutParams_ShouldCallBridge()\n        {\n            AppsFlyer.recordCrossPromoteImpression(\"appid\", \"campaign\", null);\n            mock.Received().recordCrossPromoteImpression(\"appid\", \"campaign\", null);\n        }\n\n        [Test]\n        public void AddPushNotificationDeepLinkPath_ShouldCallBridge()\n        {\n            AppsFlyer.addPushNotificationDeepLinkPath(\"path1\", \"path2\");\n            mock.Received().addPushNotificationDeepLinkPath(\"path1\", \"path2\");\n        }\n        #endregion\n\n#if UNITY_ANDROID\n    public class AppsFlyerAndroidTests\n    {\n        private IAppsFlyerAndroidBridge mock;\n\n        [SetUp]\n        public void SetUp()\n        {\n            mock = Substitute.For<IAppsFlyerAndroidBridge>();\n            AppsFlyer.instance = mock;\n        }\n\n        [Test] public void UpdateServerUninstallToken_ShouldCallBridge() => AppsFlyer.updateServerUninstallToken(\"tokenTest\");\n        [Test] public void SetImeiData_ShouldCallBridge() => AppsFlyer.setImeiData(\"imei\");\n        [Test] public void SetAndroidIdData_ShouldCallBridge() => AppsFlyer.setAndroidIdData(\"androidId\");\n        [Test] public void WaitForCustomerUserId_ShouldCallBridge() => AppsFlyer.waitForCustomerUserId(true);\n        [Test] public void SetCustomerIdAndStartSDK_ShouldCallBridge() => AppsFlyer.setCustomerIdAndStartSDK(\"01234\");\n        [Test] public void GetOutOfStore_ShouldCallBridge() => AppsFlyer.getOutOfStore();\n        [Test] public void SetOutOfStore_ShouldCallBridge() => AppsFlyer.setOutOfStore(\"test\");\n        [Test] public void SetCollectAndroidID_ShouldCallBridge() => AppsFlyer.setCollectAndroidID(true);\n        [Test] public void SetCollectIMEI_ShouldCallBridge() => AppsFlyer.setCollectIMEI(true);\n        [Test] public void SetIsUpdate_ShouldCallBridge() => AppsFlyer.setIsUpdate(true);\n        [Test] public void SetPreinstallAttribution_ShouldCallBridge() => AppsFlyer.setPreinstallAttribution(\"mediaSourceTestt\", \"campaign\", \"sideId\");\n        [Test] public void IsPreInstalledApp_ShouldCallBridge() => AppsFlyer.isPreInstalledApp();\n        [Test] public void GetAttributionId_ShouldCallBridge() => AppsFlyer.getAttributionId();\n        [Test] public void HandlePushNotifications_ShouldCallBridge() => AppsFlyer.handlePushNotifications();\n        [Test] public void ValidateAndSendInAppPurchase_ShouldCallBridge() => AppsFlyer.validateAndSendInAppPurchase(\"ewjkekwjekw\", \"hewjehwj\", \"purchaseData\", \"3.0\", \"USD\", null, null);\n        [Test] public void SetCollectOaid_ShouldCallBridge() => AppsFlyer.setCollectOaid(true);\n        [Test] public void SetDisableAdvertisingIdentifiers_ShouldCallBridge() => AppsFlyer.setDisableAdvertisingIdentifiers(true);\n        [Test] public void SetDisableNetworkData_ShouldCallBridge() => AppsFlyer.setDisableNetworkData(true);\n    }\n#endif\n\n#if UNITY_IOS\n    public class AppsFlyeriOSTests\n    {\n        private IAppsFlyerIOSBridge mock;\n\n        [SetUp]\n        public void SetUp()\n        {\n            mock = Substitute.For<IAppsFlyerIOSBridge>();\n            AppsFlyer.instance = mock;\n        }\n\n        [Test] public void DisableCollectAppleAdSupport_True_ShouldCallBridge() => AppsFlyer.setDisableCollectAppleAdSupport(true);\n        [Test] public void DisableCollectAppleAdSupport_False_ShouldCallBridge() => AppsFlyer.setDisableCollectAppleAdSupport(false);\n        [Test, System.Obsolete] public void ShouldCollectDeviceName_True_ShouldCallBridge() => AppsFlyer.setShouldCollectDeviceName(true);\n        [Test, System.Obsolete] public void ShouldCollectDeviceName_False_ShouldCallBridge() => AppsFlyer.setShouldCollectDeviceName(false);\n        [Test] public void DisableCollectIAd_True_ShouldCallBridge() => AppsFlyer.setDisableCollectIAd(true);\n        [Test] public void DisableCollectIAd_False_ShouldCallBridge() => AppsFlyer.setDisableCollectIAd(false);\n        [Test] public void UseReceiptValidationSandbox_True_ShouldCallBridge() => AppsFlyer.setUseReceiptValidationSandbox(true);\n        [Test] public void UseReceiptValidationSandbox_False_ShouldCallBridge() => AppsFlyer.setUseReceiptValidationSandbox(false);\n        [Test] public void UseUninstallSandbox_True_ShouldCallBridge() => AppsFlyer.setUseUninstallSandbox(true);\n        [Test] public void UseUninstallSandbox_False_ShouldCallBridge() => AppsFlyer.setUseUninstallSandbox(false);\n        [Test] public void ValidateAndSendInAppPurchase_ShouldCallBridge() => AppsFlyer.validateAndSendInAppPurchase(\"3d2\", \"5.0\", \"USD\", \"45\", null, null);\n        [Test] public void RegisterUninstall_ShouldCallBridge()\n        {\n            var token = System.Text.Encoding.UTF8.GetBytes(\"740f4707 bebcf74f 9b7c25d4 8e335894 5f6aa01d a5ddb387 462c7eaf 61bb78ad\");\n            AppsFlyer.registerUninstall(token);\n            mock.Received().registerUninstall(token);\n        }\n        [Test] public void HandleOpenUrl_ShouldCallBridge() => AppsFlyer.handleOpenUrl(\"www.test.com\", \"appTest\", \"test\");\n        [Test] public void WaitForATTUserAuthorizationWithTimeoutInterval_ShouldCallBridge() => AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(30);\n        [Test] public void SetCurrentDeviceLanguage_ShouldCallBridge() => AppsFlyer.setCurrentDeviceLanguage(\"en\");\n        [Test] public void DisableSKAdNetwork_True_ShouldCallBridge() => AppsFlyer.disableSKAdNetwork(true);\n        [Test] public void DisableSKAdNetwork_False_ShouldCallBridge() => AppsFlyer.disableSKAdNetwork(false);\n    }\n#endif\n\n    }\n}\n"
  },
  {
    "path": "Assets/AppsFlyer/Tests/Tests_Suite.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1b1a24aa01166451d804d7c03c14a3db\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Tests.meta",
    "content": "fileFormatVersion: 2\nguid: 1f19f272c71674582bed1d93925da003\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Windows/AppsFlyerLib.pdb.meta",
    "content": "fileFormatVersion: 2\nguid: d0748deab2f031f42b801afab0837a59\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Windows/AppsFlyerLib.pri.meta",
    "content": "fileFormatVersion: 2\nguid: c621896ec81267f478e98555031271ef\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Windows/AppsFlyerLib.winmd.meta",
    "content": "fileFormatVersion: 2\nguid: 5186898c6f4665f438e46763d4cff3ae\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 0\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 0\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 1\n      settings:\n        CPU: AnyCPU\n  - first:\n      XboxOne: XboxOne\n    second:\n      enabled: 1\n      settings: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Windows/AppsFlyerWindows.cs",
    "content": "//#define AFSDK_WIN_DEBUG\r\n//#define UNITY_WSA_10_0\r\n//#define ENABLE_WINMD_SUPPORT\r\n\r\n#if UNITY_WSA_10_0\r\nusing System;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing System.Reflection;\r\nusing System.ComponentModel;\r\nusing UnityEngine;\r\nusing System.Threading.Tasks;\r\n\r\n#if ENABLE_WINMD_SUPPORT\r\nusing AppsFlyerLib;\r\n#endif\r\n\r\nnamespace AppsFlyerSDK\r\n{\r\n    public class AppsFlyerWindows\r\n    {\r\n#if ENABLE_WINMD_SUPPORT\r\n        static private MonoBehaviour _gameObject = null;\r\n#endif\r\n\r\n        public static void InitSDK(string devKey, string appId, MonoBehaviour gameObject)\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n\r\n#if AFSDK_WIN_DEBUG\r\n            // Remove callstack\r\n            Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);\r\n#endif\r\n            Log(\"[InitSDK]: devKey: {0}, appId: {1}, gameObject: {2}\", devKey, appId, gameObject == null ? \"null\" : gameObject.ToString());\r\n            AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker();\r\n            tracker.devKey = devKey;\r\n            tracker.appId = appId;\r\n            // Interface\r\n            _gameObject = gameObject;\r\n#endif\r\n        }\r\n\r\n        public static string GetAppsFlyerId()\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n            Log(\"[GetAppsFlyerId]\");\r\n            return AppsFlyerTracker.GetAppsFlyerTracker().GetAppsFlyerUID();\r\n#else\r\n            return \"\";\r\n#endif\r\n        }\r\n\r\n        public static void SetCustomerUserId(string customerUserId)\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n            Log(\"[SetCustomerUserId] customerUserId: {0}\", customerUserId);\r\n            if (customerUserId.Contains(\"test_device:\"))\r\n            {\r\n                string testDeviceId = customerUserId.Substring(12);\r\n                AppsFlyerTracker.GetAppsFlyerTracker().testDeviceId = testDeviceId;\r\n            }\r\n            AppsFlyerTracker.GetAppsFlyerTracker().customerUserId = customerUserId;\r\n#endif\r\n        }\r\n\r\n        public static void Start()\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n            Log(\"[Start]\");\r\n            AppsFlyerTracker.GetAppsFlyerTracker().TrackAppLaunchAsync(Callback);\r\n#endif\r\n        }\r\n\r\n#if ENABLE_WINMD_SUPPORT\r\n        public static void Callback(AppsFlyerLib.ServerStatusCode code)\r\n        {\r\n            Log(\"[Callback]: {0}\", code.ToString());\r\n\r\n            AppsFlyerRequestEventArgs eventArgs = new AppsFlyerRequestEventArgs((int)code, code.ToString());\r\n            if (_gameObject != null) {\r\n                var method = _gameObject.GetType().GetMethod(\"AppsFlyerOnRequestResponse\");\r\n                if (method != null) {\r\n                    method.Invoke(_gameObject, new object[] { AppsFlyerTracker.GetAppsFlyerTracker(), eventArgs });\r\n                }\r\n            }\r\n        }\r\n#endif\r\n\r\n        public static void LogEvent(string eventName, Dictionary<string, string> eventValues)\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n            if (eventValues == null)\r\n            {\r\n                    eventValues = new Dictionary<string, string>();\r\n            }\r\n            IDictionary<string, object> result = new Dictionary<string, object>();\r\n            foreach (KeyValuePair<string, string> kvp in eventValues)\r\n            {\r\n                result.Add(kvp.Key.ToString(), kvp.Value);\r\n            }\r\n\r\n            Log(\"[LogEvent]: eventName: {0} result: {1}\", eventName, result.ToString());\r\n\r\n            AppsFlyerTracker tracker = AppsFlyerTracker.GetAppsFlyerTracker();\r\n            tracker.TrackEvent(eventName, result);\r\n\r\n#endif\r\n        }\r\n\r\n\r\n        public static void GetConversionData(string _reserved)\r\n        {\r\n#if ENABLE_WINMD_SUPPORT\r\n            Task.Run(async () =>\r\n            {\r\n                AppsFlyerLib.AppsFlyerTracker tracker = AppsFlyerLib.AppsFlyerTracker.GetAppsFlyerTracker();\r\n                string conversionData = await tracker.GetConversionDataAsync();\r\n\r\n                IAppsFlyerConversionData conversionDataHandler = _gameObject as IAppsFlyerConversionData;\r\n\r\n                if (conversionDataHandler != null)\r\n                {\r\n                    Log(\"[GetConversionData] Will call `onConversionDataSuccess` with: {0}\", conversionData);\r\n                    conversionDataHandler.onConversionDataSuccess(conversionData);\r\n                } else {\r\n                    Log(\"[GetConversionData] Object with `IAppsFlyerConversionData` interface not found! Check `InitSDK` implementation\");\r\n                }\r\n                // _gameObject.GetType().GetMethod(\"onConversionDataSuccess\").Invoke(_gameObject, new[] { conversionData });\r\n            });\r\n#endif\r\n        }\r\n\r\n        private static void Log(string format, params string[] args)\r\n        {\r\n#if AFSDK_WIN_DEBUG\r\n#if ENABLE_WINMD_SUPPORT\r\n            Debug.Log(\"AF_UNITY_WSA_10_0\" + String.Format(format, args));\r\n#endif\r\n#endif\r\n        }\r\n\r\n    }\r\n\r\n}\r\n#endif\r\n"
  },
  {
    "path": "Assets/AppsFlyer/Windows/AppsFlyerWindows.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 034d11e52b599954181d7f08c0d89ca8\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/Windows.meta",
    "content": "fileFormatVersion: 2\nguid: 1fbfcb6aeaa7f40e69a0daff450a2450\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer/package.json",
    "content": "{\n\t\"name\": \"appsflyer-unity-plugin\",\n\t\"displayName\": \"AppsFlyer\",\n\t\"description\": \"AppsFlyer Unity plugin\",\n\t\"version\": \"6.17.91\",\n\t\"unity\": \"2019.4\",\n\t\"license\": \"MIT\"\n  }\n"
  },
  {
    "path": "Assets/AppsFlyer/package.json.meta",
    "content": "fileFormatVersion: 2\nguid: a2b3ab5da7dda473b8791503604647b4\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/AppsFlyer.meta",
    "content": "fileFormatVersion: 2\nguid: 7863556d88b814e09ba9cfc75a91d655\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Versions\n\n## v6.17.91\n* Update Android unity-wrapper to Billing Library 8 (billing:8.0.0)\n\n## v6.17.90\n* Update Android SDK version - 6.17.6\n* Update iOS SDK version - 6.17.9\n* Update iOS Purchase Connector version - 6.17.9\n* Two unity-wrapper variants published:\n  * v6.17.90 — Billing Library 7 (billing:5.2.0)\n  * v6.17.91 — Billing Library 8 (billing:8.0.0)\n* Update appsflyer_logo\n\n## v6.17.81\n* Update Android Purchase Connector version - 2.2.0\n\n## v6.17.80\n* Update Android SDK version - 6.17.5\n* Update Android Purchase Connector version - 2.1.2\n* Update iOS SDK version - 6.17.8\n* Update iOS Purchase Connector version - 6.17.8\n\n## v6.17.72\n* Use Android Purchase Connector version - 2.1.1\n\n## v6.17.71\n* Use Android Purchase Connector version - 2.1.0\n  \n## v6.17.7\n* Update iOS SDK version - 6.17.7\n* Update iOS Purchase Connector version - 6.17.7\n* Update Android Purchase Connector version - 2.2.0\n\n## v6.17.5\n* Update iOS SDK version - 6.17.5\n* Update iOS Purchase Connector version - 6.17.5\n* Update Android SDK ersion - 6.17.3\n* Validate and log API changes.\n\n## v6.17.1\n* Purchase Connector support.\n* Update iOS SDK version - 6.17.1\n* Update Android SDK ersion - 6.17.0\n\n## v6.16.21\n* Bug fix - AppsflyerConsent - nonGDPR init\n\n## v6.16.2\n* Update iOS SDK version - 6.16.2\n* Update Android SDK version - 6.16.2\n* Update AppsflyerConsent object and methods + deprecation of old methods\n\n## v6.16.0\n* Update iOS SDK version - 6.16.0\n* Update Android SDK version - 6.16.0\n\n## v6.15.3\n* Fix logAdRevenue - revenue value will not be rounded\n\n## v6.15.2\n* Update iOS SDK version - 6.15.2\n\n## v6.15.1\n* Update iOS SDK version - 6.15.1\n* Update Android SDK version - 6.15.0\n* Added new iOS and Android API `logAdRevenue`\n\n## v6.14.5\n* Update iOS SDK version - 6.14.5\n\n## v6.14.4\n* Update iOS SDK version - 6.14.4\n* Update Android SDK version - 6.14.2\n\n## v6.14.3\n* Update iOS SDK version - 6.14.3\n* Update Android SDK version - 6.14.0\n* Added new version of iOS and Android API `validateAndSendInAppPurchase`\n(This API is currently in closed beta. Please contact AppsFlyer before using it).\n* Android Huawei install referrer update - [huawei-install-referrer](https://dev.appsflyer.com/hc/docs/install-android-sdk#huawei-install-referrer)\n\n\n## v6.14.0\n* Update iOS SDK version - 6.14.0\n* iOS Privacy Manifest support, [for more information about privacy manifest](https://support.appsflyer.com/hc/en-us/articles/21677433322641-Privacy-Manifest)\n* Xcode 15.3 bug fix\n\n## v6.13.10\n* Update iOS SDK version - 6.13.1\n\n## v6.13.0\n* Update iOS SDK version - 6.13.0\n* Update Android SDK version - 6.13.0\n* Added new iOS and Android API `setDeepLinkTimeout`\n* Added new iOS and Android API `enableTCFDataCollection`\n* Added new iOS and Android API `setConsentData`\n\n## v6.12.22\n* Update EDM4U - 1.2.177\n* Fix AFUnityUtils import\n\n## v6.12.21\n* Update iOS SDK version - 6.12.2\n\n## v6.12.20\n* Update iOS SDK version - 6.12.1\n* Update Android SDK version - 6.12.2\n* UPM distribution change, [see breaking changes](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/tree/development#------breaking-changes-when-updating-to-61220-).\n* Added new iOS API `disableIDFVCollection`\n\n## v6.12.10\n* Update iOS SDK version - 6.12.0\n* Update Android SDK version - 6.12.1\n\n## v6.10.30\n* Update iOS SDK version - 6.10.1\n* Update Android SDK version - 6.10.3\n\n## v6.10.10\n* Update iOS SDK version - 6.10.0\n* Update Android SDK version - 6.10.1\n* Fix NullReferenceException when not using Request Listeners with UWP\n* Align `setHost`, `disableSKAdNetwork` and `setCurrencyCode` to work if called prior to `initSdk`\n\n## v6.9.4\n* Update iOS SDK version - 6.9.1\n* Update Android SDK version - 6.9.4\n* Fix appsflyer logo on prefab\n* Fix attributeAndOpenStore issue on Android\n\n## v6.8.5\n* Fix setHost API for iOS\n\n## v6.8.4\n* Fix package\n\n## v6.8.3\n* Fix android issue\n* Fix in-app callback issue\n\n## v6.8.2\n* Fix dependency for strict mode\n\n## v6.8.1\n* Update iOS SDK version - 6.8.1\n* Update Android SDK version - 6.8.0\n* Added new Android API `setDisableNetworkData`\n\n## v6.6.0\n* Update iOS SDK version - 6.6.0\n* Update Android SDK version - 6.6.0\n* add new API setPartnerData\n* Beta support for MacOS\n\n## v6.5.4\n* Update iOS SDK version - 6.5.4\n* Update Android SDK version - 6.5.4\n\n## v6.5.3\n* Additional solution for Swizzling using macroprocessor\n\n## v6.5.2\n* Update iOS SDK version - 6.5.2\n* Update Android SDK version - 6.5.2\n\n## v6.4.41\n* Fix issue with deep linking\n* `getAppsFlyerUID` support for uwp\n\n## v6.4.4\n* Update iOS SDK version - 6.4.4\n* Update Android SDK version - 6.4.3\n* Fixed issue with deep linking\n\n## v6.4.1\n* Update iOS SDK version - 6.4.1\n* Update Android SDK version - 6.4.1\n* Fixed a bug causing a crash in Unity apps\n\n## v6.4.0\n* Update iOS SDK version - 6.4.0\n* Update Android SDK version - 6.4.0\n* new API `setSharingFilterForPartners`\n* Deprecated API `setSharingFilterForAllPartners` and `setSharingFilter`\n* Android Target API updated to 30\n\n## v6.3.5\n* Update iOS SDK version - 6.3.5\n* Fix issue with Facebook login\n* Fix issue with uwp\n\n## v6.3.2\n* Update iOS SDK version - 6.3.2\n* Update Android SDK version - 6.3.2\n* new Android API `setDisableAdvertisingIdentifiers`\n\n## v6.3.1\n* Update iOS SDK version - 6.3.1\n\n\n## v6.3.0\n* Support for UWP\n* Update iOS SDK version - 6.3.0\n* Update Android SDK version - 6.3.0\n\n## v6.2.63\n* fix swizzling DDL\n\n## v6.2.62\n\n* fix setOneLinkCustomDomains API\n* fix swizzling\n\n## v6.2.61\n\n* Fix android dependency\n\n## v6.2.6\n\n* Update iOS SDK version - 6.2.6\n* Update Android SDK version - 6.2.3\n\n## v6.2.5\n\n* Update iOS SDK version - 6.2.5\n* Deprecated setShouldCollectDeviceName\n* AttributionObject to handle DeepLink\n\n## v6.2.41\n\n* Fix Skad issue\n\n## v6.2.4\n\n* RD-59026 - iOS SDK Version - 6.2.4\n\n## v6.2.3\n\n* RD-54266 - iOS SDK Version - 6.2.3\n\n## v6.2.2\n\n* RD-54266 - iOS SDK Version - 6.2.2\n* RD-54266 - Android SDK Version - 6.2.0\n\n## v6.2.0\n\n* RD-55161 - Fixed don't call start before startSDK() (iOS) \n* RD-55566 - Fix onAppOpenAttribution called from kill for swizziling class (iOS)\n* RD-45032 - Send reponse code in Purchase Validation Error (iOS) \n* RD-54266 - iOS SDK Version - 6.2.0\n* RD-54266 - Android SDK Version - 6.1.4\n\n## v6.1.4\n\n* RD-55566 - Fix onAppOpenAttribution called from kill\n\n## v6.1.3\n\n* RD-50954 - Added Unified Deep Linking API\n* RD-54264 - Added addPushNotificationDeepLinkPath api for iOS & Android\n* RD-54266 - iOS SDK Version - 6.1.3\n* RD-54266 - Android SDK Version - 6.1.3\n\n## v6.1.0\n\n* iOS SDK Version - 6.1.1\n* Android SDK Version - 6.1.0\n* Added onRequestResponse and onInAppResponse events.\n\n## v6.0.7\n\n* RD-49435 - ios swizzle options fix\n* iOS SDK Version - 6.0.7\n\n\n## v6.0.6\n\n* RD-48888 - continueUserActivity remove super call\n* RD-48915 - AppsFlyer+AppController update to lastest version\n\n## v6.0.5\n\n* iOS SDK Version - 6.0.5\n\n\n## 6.0.3\n\n* RD-44538 - empty game object fix\n* Added disableSKAdNetwork api\n* Added waitForATTUserAuthorizationWithTimeoutInterval api\n* Update android [installreferrer](https://mvnrepository.com/artifact/com.android.installreferrer/installreferrer) to 2.1 \n* Android SDK Version - 5.4.3\n* iOS SDK Version - 6.0.3\n\n\n## 5.4.2\n\n* RD-43178 - added setSharingFilterForAllPartners() api\n* RD-43178 - added setSharingFilter(params string[] partners) api\n* RD-42761 - fix validateAndSendInAppPurchase callback on iOS\n\n## 5.4.1\n\n* RD-40404 - add additional params for recordCrossPromoteImpression api (ios & android)\n* RD-42760 - add setPhoneNumber api (ios & android)\n* RD-42761 - fix validateAndSendInAppPurchase callback on iOS\n\n* Android SDK Version - 5.4.1\n* iOS SDK Version     - 5.4.1\n\n## 5.3.1\n\n* RD-39294 - add super call from continueUserActivity\n* RD-39255 - make IAppsFlyerConversionData public\t\n* RD-39254 - add setCollectOaid api (android)\n* RD-39216 - add handleOpenUrl api (iOS)\n\n\n## 5.3.0\n\n* Android SDK Version - 5.3.0\n* iOS SDK Version.    - 5.3.0\n* Prefab fix for unity 2018.2.21f\n\n## 5.2.1\n\n* RD-37433 - Fix for 'duplicate symbol '__sendEvent' issue\n\n## 5.2.0\n\n\n* Android SDK Version - 5.2.0\n* iOS SDK Version.    - 5.2.0\n\nChanges and fixes: \n - New plugin with breaking changes. Please see migration doc with details.\n\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 AppsFlyerSDK\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": "ProjectSettings/AudioManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!11 &1\nAudioManager:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  m_Volume: 1\n  Rolloff Scale: 1\n  Doppler Factor: 1\n  Default Speaker Mode: 2\n  m_SampleRate: 0\n  m_DSPBufferSize: 1024\n  m_VirtualVoiceCount: 512\n  m_RealVoiceCount: 32\n  m_EnableOutputSuspension: 1\n  m_SpatializerPlugin: \n  m_AmbisonicDecoderPlugin: \n  m_DisableAudio: 0\n  m_VirtualizeEffects: 1\n  m_RequestedDSPBufferSize: 0\n"
  },
  {
    "path": "ProjectSettings/ClusterInputManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!236 &1\nClusterInputManager:\n  m_ObjectHideFlags: 0\n  m_Inputs: []\n"
  },
  {
    "path": "ProjectSettings/DynamicsManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!55 &1\nPhysicsManager:\n  m_ObjectHideFlags: 0\n  serializedVersion: 13\n  m_Gravity: {x: 0, y: -9.81, z: 0}\n  m_DefaultMaterial: {fileID: 0}\n  m_BounceThreshold: 2\n  m_SleepThreshold: 0.005\n  m_DefaultContactOffset: 0.01\n  m_DefaultSolverIterations: 6\n  m_DefaultSolverVelocityIterations: 1\n  m_QueriesHitBackfaces: 0\n  m_QueriesHitTriggers: 1\n  m_EnableAdaptiveForce: 0\n  m_ClothInterCollisionDistance: 0.1\n  m_ClothInterCollisionStiffness: 0.2\n  m_ContactsGeneration: 1\n  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n  m_AutoSimulation: 1\n  m_AutoSyncTransforms: 0\n  m_ReuseCollisionCallbacks: 0\n  m_ClothInterCollisionSettingsToggle: 0\n  m_ClothGravity: {x: 0, y: -9.81, z: 0}\n  m_ContactPairsMode: 0\n  m_BroadphaseType: 0\n  m_WorldBounds:\n    m_Center: {x: 0, y: 0, z: 0}\n    m_Extent: {x: 250, y: 250, z: 250}\n  m_WorldSubdivisions: 8\n  m_FrictionType: 0\n  m_EnableEnhancedDeterminism: 0\n  m_EnableUnifiedHeightmaps: 1\n  m_SolverType: 0\n  m_DefaultMaxAngularSpeed: 50\n"
  },
  {
    "path": "ProjectSettings/EditorBuildSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!1045 &1\nEditorBuildSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  m_Scenes: []\n  m_configObjects: {}\n"
  },
  {
    "path": "ProjectSettings/EditorSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!159 &1\nEditorSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 9\n  m_ExternalVersionControlSupport: Visible Meta Files\n  m_SerializationMode: 2\n  m_LineEndingsForNewScripts: 1\n  m_DefaultBehaviorMode: 0\n  m_PrefabRegularEnvironment: {fileID: 0}\n  m_PrefabUIEnvironment: {fileID: 0}\n  m_SpritePackerMode: 0\n  m_SpritePackerPaddingPower: 1\n  m_EtcTextureCompressorBehavior: 1\n  m_EtcTextureFastCompressor: 1\n  m_EtcTextureNormalCompressor: 2\n  m_EtcTextureBestCompressor: 4\n  m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp\n  m_ProjectGenerationRootNamespace: \n  m_CollabEditorSettings:\n    inProgressEnabled: 1\n  m_EnableTextureStreamingInEditMode: 1\n  m_EnableTextureStreamingInPlayMode: 1\n  m_AsyncShaderCompilation: 1\n  m_EnterPlayModeOptionsEnabled: 0\n  m_EnterPlayModeOptions: 3\n  m_ShowLightmapResolutionOverlay: 1\n  m_UseLegacyProbeSampleCount: 0\n  m_AssetPipelineMode: 1\n  m_CacheServerMode: 0\n  m_CacheServerEndpoint: \n  m_CacheServerNamespacePrefix: default\n  m_CacheServerEnableDownload: 1\n  m_CacheServerEnableUpload: 1\n"
  },
  {
    "path": "ProjectSettings/GraphicsSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!30 &1\nGraphicsSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 13\n  m_Deferred:\n    m_Mode: 1\n    m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}\n  m_DeferredReflections:\n    m_Mode: 1\n    m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}\n  m_ScreenSpaceShadows:\n    m_Mode: 1\n    m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}\n  m_LegacyDeferred:\n    m_Mode: 1\n    m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}\n  m_DepthNormals:\n    m_Mode: 1\n    m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}\n  m_MotionVectors:\n    m_Mode: 1\n    m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}\n  m_LightHalo:\n    m_Mode: 1\n    m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}\n  m_LensFlare:\n    m_Mode: 1\n    m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}\n  m_AlwaysIncludedShaders:\n  - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}\n  - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}\n  m_PreloadedShaders: []\n  m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,\n    type: 0}\n  m_CustomRenderPipeline: {fileID: 0}\n  m_TransparencySortMode: 0\n  m_TransparencySortAxis: {x: 0, y: 0, z: 1}\n  m_DefaultRenderingPath: 1\n  m_DefaultMobileRenderingPath: 1\n  m_TierSettings: []\n  m_LightmapStripping: 0\n  m_FogStripping: 0\n  m_InstancingStripping: 0\n  m_LightmapKeepPlain: 1\n  m_LightmapKeepDirCombined: 1\n  m_LightmapKeepDynamicPlain: 1\n  m_LightmapKeepDynamicDirCombined: 1\n  m_LightmapKeepShadowMask: 1\n  m_LightmapKeepSubtractive: 1\n  m_FogKeepLinear: 1\n  m_FogKeepExp: 1\n  m_FogKeepExp2: 1\n  m_AlbedoSwatchInfos: []\n  m_LightsUseLinearIntensity: 0\n  m_LightsUseColorTemperature: 0\n  m_LogWhenShaderIsCompiled: 0\n  m_AllowEnlightenSupportForUpgradedProject: 0\n"
  },
  {
    "path": "ProjectSettings/InputManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!13 &1\nInputManager:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  m_Axes:\n  - serializedVersion: 3\n    m_Name: Horizontal\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: left\n    positiveButton: right\n    altNegativeButton: a\n    altPositiveButton: d\n    gravity: 3\n    dead: 0.001\n    sensitivity: 3\n    snap: 1\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Vertical\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: down\n    positiveButton: up\n    altNegativeButton: s\n    altPositiveButton: w\n    gravity: 3\n    dead: 0.001\n    sensitivity: 3\n    snap: 1\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire1\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left ctrl\n    altNegativeButton: \n    altPositiveButton: mouse 0\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire2\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left alt\n    altNegativeButton: \n    altPositiveButton: mouse 1\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire3\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: left shift\n    altNegativeButton: \n    altPositiveButton: mouse 2\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Jump\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: space\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse X\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: 0.1\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse Y\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: 0.1\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 1\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Mouse ScrollWheel\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0\n    sensitivity: 0.1\n    snap: 0\n    invert: 0\n    type: 1\n    axis: 2\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Horizontal\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0.19\n    sensitivity: 1\n    snap: 0\n    invert: 0\n    type: 2\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Vertical\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: \n    altNegativeButton: \n    altPositiveButton: \n    gravity: 0\n    dead: 0.19\n    sensitivity: 1\n    snap: 0\n    invert: 1\n    type: 2\n    axis: 1\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire1\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 0\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire2\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 1\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Fire3\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 2\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Jump\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: joystick button 3\n    altNegativeButton: \n    altPositiveButton: \n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Submit\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: return\n    altNegativeButton: \n    altPositiveButton: joystick button 0\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Submit\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: enter\n    altNegativeButton: \n    altPositiveButton: space\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n  - serializedVersion: 3\n    m_Name: Cancel\n    descriptiveName: \n    descriptiveNegativeName: \n    negativeButton: \n    positiveButton: escape\n    altNegativeButton: \n    altPositiveButton: joystick button 1\n    gravity: 1000\n    dead: 0.001\n    sensitivity: 1000\n    snap: 0\n    invert: 0\n    type: 0\n    axis: 0\n    joyNum: 0\n"
  },
  {
    "path": "ProjectSettings/MemorySettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!387306366 &1\nMemorySettings:\n  m_ObjectHideFlags: 0\n  m_EditorMemorySettings:\n    m_MainAllocatorBlockSize: -1\n    m_ThreadAllocatorBlockSize: -1\n    m_MainGfxBlockSize: -1\n    m_ThreadGfxBlockSize: -1\n    m_CacheBlockSize: -1\n    m_TypetreeBlockSize: -1\n    m_ProfilerBlockSize: -1\n    m_ProfilerEditorBlockSize: -1\n    m_BucketAllocatorGranularity: -1\n    m_BucketAllocatorBucketsCount: -1\n    m_BucketAllocatorBlockSize: -1\n    m_BucketAllocatorBlockCount: -1\n    m_ProfilerBucketAllocatorGranularity: -1\n    m_ProfilerBucketAllocatorBucketsCount: -1\n    m_ProfilerBucketAllocatorBlockSize: -1\n    m_ProfilerBucketAllocatorBlockCount: -1\n    m_TempAllocatorSizeMain: -1\n    m_JobTempAllocatorBlockSize: -1\n    m_BackgroundJobTempAllocatorBlockSize: -1\n    m_JobTempAllocatorReducedBlockSize: -1\n    m_TempAllocatorSizeGIBakingWorker: -1\n    m_TempAllocatorSizeNavMeshWorker: -1\n    m_TempAllocatorSizeAudioWorker: -1\n    m_TempAllocatorSizeCloudWorker: -1\n    m_TempAllocatorSizeGfx: -1\n    m_TempAllocatorSizeJobWorker: -1\n    m_TempAllocatorSizeBackgroundWorker: -1\n    m_TempAllocatorSizePreloadManager: -1\n  m_PlatformMemorySettings: {}\n"
  },
  {
    "path": "ProjectSettings/MultiplayerManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!655991488 &1\nMultiplayerManager:\n  m_ObjectHideFlags: 0\n  m_EnableMultiplayerRoles: 0\n  m_StrippingTypes: {}\n"
  },
  {
    "path": "ProjectSettings/NavMeshAreas.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!126 &1\nNavMeshProjectSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  areas:\n  - name: Walkable\n    cost: 1\n  - name: Not Walkable\n    cost: 1\n  - name: Jump\n    cost: 2\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  - name: \n    cost: 1\n  m_LastAgentTypeID: -887442657\n  m_Settings:\n  - serializedVersion: 2\n    agentTypeID: 0\n    agentRadius: 0.5\n    agentHeight: 2\n    agentSlope: 45\n    agentClimb: 0.75\n    ledgeDropHeight: 0\n    maxJumpAcrossDistance: 0\n    minRegionArea: 2\n    manualCellSize: 0\n    cellSize: 0.16666667\n    manualTileSize: 0\n    tileSize: 256\n    accuratePlacement: 0\n    debug:\n      m_Flags: 0\n  m_SettingNames:\n  - Humanoid\n"
  },
  {
    "path": "ProjectSettings/PackageManagerSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!114 &1\nMonoBehaviour:\n  m_ObjectHideFlags: 61\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_ScopedRegistriesSettingsExpanded: 1\n  oneTimeWarningShown: 0\n  m_Registries:\n  - m_Id: main\n    m_Name: \n    m_Url: https://packages.unity.com\n    m_Scopes: []\n    m_IsDefault: 1\n  m_UserSelectedRegistryName: \n  m_UserAddingNewScopedRegistry: 0\n  m_RegistryInfoDraft:\n    m_ErrorMessage: \n    m_Original:\n      m_Id: \n      m_Name: \n      m_Url: \n      m_Scopes: []\n      m_IsDefault: 0\n    m_Modified: 0\n    m_Name: \n    m_Url: \n    m_Scopes:\n    - \n    m_SelectedScopeIndex: 0\n"
  },
  {
    "path": "ProjectSettings/Physics2DSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!19 &1\nPhysics2DSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 4\n  m_Gravity: {x: 0, y: -9.81}\n  m_DefaultMaterial: {fileID: 0}\n  m_VelocityIterations: 8\n  m_PositionIterations: 3\n  m_VelocityThreshold: 1\n  m_MaxLinearCorrection: 0.2\n  m_MaxAngularCorrection: 8\n  m_MaxTranslationSpeed: 100\n  m_MaxRotationSpeed: 360\n  m_BaumgarteScale: 0.2\n  m_BaumgarteTimeOfImpactScale: 0.75\n  m_TimeToSleep: 0.5\n  m_LinearSleepTolerance: 0.01\n  m_AngularSleepTolerance: 2\n  m_DefaultContactOffset: 0.01\n  m_JobOptions:\n    serializedVersion: 2\n    useMultithreading: 0\n    useConsistencySorting: 0\n    m_InterpolationPosesPerJob: 100\n    m_NewContactsPerJob: 30\n    m_CollideContactsPerJob: 100\n    m_ClearFlagsPerJob: 200\n    m_ClearBodyForcesPerJob: 200\n    m_SyncDiscreteFixturesPerJob: 50\n    m_SyncContinuousFixturesPerJob: 50\n    m_FindNearestContactsPerJob: 100\n    m_UpdateTriggerContactsPerJob: 100\n    m_IslandSolverCostThreshold: 100\n    m_IslandSolverBodyCostScale: 1\n    m_IslandSolverContactCostScale: 10\n    m_IslandSolverJointCostScale: 10\n    m_IslandSolverBodiesPerJob: 50\n    m_IslandSolverContactsPerJob: 50\n  m_AutoSimulation: 1\n  m_QueriesHitTriggers: 1\n  m_QueriesStartInColliders: 1\n  m_CallbacksOnDisable: 1\n  m_ReuseCollisionCallbacks: 0\n  m_AutoSyncTransforms: 0\n  m_AlwaysShowColliders: 0\n  m_ShowColliderSleep: 1\n  m_ShowColliderContacts: 0\n  m_ShowColliderAABB: 0\n  m_ContactArrowScale: 0.2\n  m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}\n  m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}\n  m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}\n  m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}\n  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "ProjectSettings/PresetManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!1386491679 &1\nPresetManager:\n  m_ObjectHideFlags: 0\n  serializedVersion: 2\n  m_DefaultPresets: {}\n"
  },
  {
    "path": "ProjectSettings/ProjectSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!129 &1\nPlayerSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 23\n  productGUID: 5190ae4a335a1487590079a7f228b806\n  AndroidProfiler: 0\n  AndroidFilterTouchesWhenObscured: 0\n  AndroidEnableSustainedPerformanceMode: 0\n  defaultScreenOrientation: 4\n  targetDevice: 2\n  useOnDemandResources: 0\n  accelerometerFrequency: 60\n  companyName: DefaultCompany\n  productName: appsflyer-unity-plugin\n  defaultCursor: {fileID: 0}\n  cursorHotspot: {x: 0, y: 0}\n  m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}\n  m_ShowUnitySplashScreen: 1\n  m_ShowUnitySplashLogo: 1\n  m_SplashScreenOverlayOpacity: 1\n  m_SplashScreenAnimation: 1\n  m_SplashScreenLogoStyle: 1\n  m_SplashScreenDrawMode: 0\n  m_SplashScreenBackgroundAnimationZoom: 1\n  m_SplashScreenLogoAnimationZoom: 1\n  m_SplashScreenBackgroundLandscapeAspect: 1\n  m_SplashScreenBackgroundPortraitAspect: 1\n  m_SplashScreenBackgroundLandscapeUvs:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1\n    height: 1\n  m_SplashScreenBackgroundPortraitUvs:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1\n    height: 1\n  m_SplashScreenLogos: []\n  m_VirtualRealitySplashScreen: {fileID: 0}\n  m_HolographicTrackingLossScreen: {fileID: 0}\n  defaultScreenWidth: 1024\n  defaultScreenHeight: 768\n  defaultScreenWidthWeb: 960\n  defaultScreenHeightWeb: 600\n  m_StereoRenderingPath: 0\n  m_ActiveColorSpace: 0\n  m_MTRendering: 1\n  mipStripping: 0\n  numberOfMipsStripped: 0\n  m_StackTraceTypes: 010000000100000001000000010000000100000001000000\n  iosShowActivityIndicatorOnLoading: -1\n  androidShowActivityIndicatorOnLoading: -1\n  iosUseCustomAppBackgroundBehavior: 0\n  iosAllowHTTPDownload: 1\n  allowedAutorotateToPortrait: 1\n  allowedAutorotateToPortraitUpsideDown: 1\n  allowedAutorotateToLandscapeRight: 1\n  allowedAutorotateToLandscapeLeft: 1\n  useOSAutorotation: 1\n  use32BitDisplayBuffer: 1\n  preserveFramebufferAlpha: 0\n  disableDepthAndStencilBuffers: 0\n  androidStartInFullscreen: 1\n  androidRenderOutsideSafeArea: 1\n  androidUseSwappy: 0\n  androidBlitType: 0\n  androidResizableWindow: 0\n  androidDefaultWindowWidth: 1920\n  androidDefaultWindowHeight: 1080\n  androidMinimumWindowWidth: 400\n  androidMinimumWindowHeight: 300\n  androidFullscreenMode: 1\n  defaultIsNativeResolution: 1\n  macRetinaSupport: 1\n  runInBackground: 1\n  captureSingleScreen: 0\n  muteOtherAudioSources: 0\n  Prepare IOS For Recording: 0\n  Force IOS Speakers When Recording: 0\n  deferSystemGesturesMode: 0\n  hideHomeButton: 0\n  submitAnalytics: 1\n  usePlayerLog: 1\n  bakeCollisionMeshes: 0\n  forceSingleInstance: 0\n  useFlipModelSwapchain: 1\n  resizableWindow: 0\n  useMacAppStoreValidation: 0\n  macAppStoreCategory: public.app-category.games\n  gpuSkinning: 0\n  xboxPIXTextureCapture: 0\n  xboxEnableAvatar: 0\n  xboxEnableKinect: 0\n  xboxEnableKinectAutoTracking: 0\n  xboxEnableFitness: 0\n  visibleInBackground: 1\n  allowFullscreenSwitch: 1\n  fullscreenMode: 1\n  xboxSpeechDB: 0\n  xboxEnableHeadOrientation: 0\n  xboxEnableGuest: 0\n  xboxEnablePIXSampling: 0\n  metalFramebufferOnly: 0\n  xboxOneResolution: 0\n  xboxOneSResolution: 0\n  xboxOneXResolution: 3\n  xboxOneMonoLoggingLevel: 0\n  xboxOneLoggingLevel: 1\n  xboxOneDisableEsram: 0\n  xboxOneEnableTypeOptimization: 0\n  xboxOnePresentImmediateThreshold: 0\n  switchQueueCommandMemory: 1048576\n  switchQueueControlMemory: 16384\n  switchQueueComputeMemory: 262144\n  switchNVNShaderPoolsGranularity: 33554432\n  switchNVNDefaultPoolsGranularity: 16777216\n  switchNVNOtherPoolsGranularity: 16777216\n  switchNVNMaxPublicTextureIDCount: 0\n  switchNVNMaxPublicSamplerIDCount: 0\n  stadiaPresentMode: 0\n  stadiaTargetFramerate: 0\n  vulkanNumSwapchainBuffers: 3\n  vulkanEnableSetSRGBWrite: 0\n  vulkanEnablePreTransform: 0\n  vulkanEnableLateAcquireNextImage: 0\n  vulkanEnableCommandBufferRecycling: 1\n  m_SupportedAspectRatios:\n    4:3: 1\n    5:4: 1\n    16:10: 1\n    16:9: 1\n    Others: 1\n  bundleVersion: 1.0\n  preloadedAssets: []\n  metroInputSource: 0\n  wsaTransparentSwapchain: 0\n  m_HolographicPauseOnTrackingLoss: 1\n  xboxOneDisableKinectGpuReservation: 1\n  xboxOneEnable7thCore: 1\n  vrSettings:\n    enable360StereoCapture: 0\n  isWsaHolographicRemotingEnabled: 0\n  enableFrameTimingStats: 0\n  enableOpenGLProfilerGPURecorders: 1\n  useHDRDisplay: 0\n  D3DHDRBitDepth: 0\n  m_ColorGamuts: 00000000\n  targetPixelDensity: 30\n  resolutionScalingMode: 0\n  resetResolutionOnWindowResize: 0\n  androidSupportedAspectRatio: 1\n  androidMaxAspectRatio: 2.1\n  applicationIdentifier: {}\n  buildNumber:\n    Standalone: 0\n    iPhone: 0\n    tvOS: 0\n  overrideDefaultApplicationIdentifier: 0\n  AndroidBundleVersionCode: 1\n  AndroidMinSdkVersion: 22\n  AndroidTargetSdkVersion: 0\n  AndroidPreferredInstallLocation: 1\n  aotOptions: \n  stripEngineCode: 1\n  iPhoneStrippingLevel: 0\n  iPhoneScriptCallOptimization: 0\n  ForceInternetPermission: 0\n  ForceSDCardPermission: 0\n  CreateWallpaper: 0\n  APKExpansionFiles: 0\n  keepLoadedShadersAlive: 0\n  StripUnusedMeshComponents: 0\n  VertexChannelCompressionMask: 4054\n  iPhoneSdkVersion: 988\n  iOSTargetOSVersionString: 11.0\n  tvOSSdkVersion: 0\n  tvOSRequireExtendedGameController: 0\n  tvOSTargetOSVersionString: 11.0\n  uIPrerenderedIcon: 0\n  uIRequiresPersistentWiFi: 0\n  uIRequiresFullScreen: 1\n  uIStatusBarHidden: 1\n  uIExitOnSuspend: 0\n  uIStatusBarStyle: 0\n  appleTVSplashScreen: {fileID: 0}\n  appleTVSplashScreen2x: {fileID: 0}\n  tvOSSmallIconLayers: []\n  tvOSSmallIconLayers2x: []\n  tvOSLargeIconLayers: []\n  tvOSLargeIconLayers2x: []\n  tvOSTopShelfImageLayers: []\n  tvOSTopShelfImageLayers2x: []\n  tvOSTopShelfImageWideLayers: []\n  tvOSTopShelfImageWideLayers2x: []\n  iOSLaunchScreenType: 0\n  iOSLaunchScreenPortrait: {fileID: 0}\n  iOSLaunchScreenLandscape: {fileID: 0}\n  iOSLaunchScreenBackgroundColor:\n    serializedVersion: 2\n    rgba: 0\n  iOSLaunchScreenFillPct: 100\n  iOSLaunchScreenSize: 100\n  iOSLaunchScreenCustomXibPath: \n  iOSLaunchScreeniPadType: 0\n  iOSLaunchScreeniPadImage: {fileID: 0}\n  iOSLaunchScreeniPadBackgroundColor:\n    serializedVersion: 2\n    rgba: 0\n  iOSLaunchScreeniPadFillPct: 100\n  iOSLaunchScreeniPadSize: 100\n  iOSLaunchScreeniPadCustomXibPath: \n  iOSLaunchScreenCustomStoryboardPath: \n  iOSLaunchScreeniPadCustomStoryboardPath: \n  iOSDeviceRequirements: []\n  iOSURLSchemes: []\n  macOSURLSchemes: []\n  iOSBackgroundModes: 0\n  iOSMetalForceHardShadows: 0\n  metalEditorSupport: 1\n  metalAPIValidation: 1\n  iOSRenderExtraFrameOnPause: 0\n  iosCopyPluginsCodeInsteadOfSymlink: 0\n  appleDeveloperTeamID: \n  iOSManualSigningProvisioningProfileID: \n  tvOSManualSigningProvisioningProfileID: \n  iOSManualSigningProvisioningProfileType: 0\n  tvOSManualSigningProvisioningProfileType: 0\n  appleEnableAutomaticSigning: 0\n  iOSRequireARKit: 0\n  iOSAutomaticallyDetectAndAddCapabilities: 1\n  appleEnableProMotion: 0\n  shaderPrecisionModel: 0\n  clonedFromGUID: 00000000000000000000000000000000\n  templatePackageId: \n  templateDefaultScene: \n  useCustomMainManifest: 0\n  useCustomLauncherManifest: 0\n  useCustomMainGradleTemplate: 0\n  useCustomLauncherGradleManifest: 0\n  useCustomBaseGradleTemplate: 0\n  useCustomGradlePropertiesTemplate: 0\n  useCustomProguardFile: 0\n  AndroidTargetArchitectures: 1\n  AndroidTargetDevices: 0\n  AndroidSplashScreenScale: 0\n  androidSplashScreen: {fileID: 0}\n  AndroidKeystoreName: \n  AndroidKeyaliasName: \n  AndroidBuildApkPerCpuArchitecture: 0\n  AndroidTVCompatibility: 0\n  AndroidIsGame: 1\n  AndroidEnableTango: 0\n  androidEnableBanner: 1\n  androidUseLowAccuracyLocation: 0\n  androidUseCustomKeystore: 0\n  m_AndroidBanners:\n  - width: 320\n    height: 180\n    banner: {fileID: 0}\n  androidGamepadSupportLevel: 0\n  chromeosInputEmulation: 1\n  AndroidMinifyWithR8: 0\n  AndroidMinifyRelease: 0\n  AndroidMinifyDebug: 0\n  AndroidValidateAppBundleSize: 1\n  AndroidAppBundleSizeToValidate: 150\n  m_BuildTargetIcons: []\n  m_BuildTargetPlatformIcons:\n  - m_BuildTarget: iPhone\n    m_Icons:\n    - m_Textures: []\n      m_Width: 180\n      m_Height: 180\n      m_Kind: 0\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 120\n      m_Height: 120\n      m_Kind: 0\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 167\n      m_Height: 167\n      m_Kind: 0\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 152\n      m_Height: 152\n      m_Kind: 0\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 76\n      m_Height: 76\n      m_Kind: 0\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 120\n      m_Height: 120\n      m_Kind: 3\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 80\n      m_Height: 80\n      m_Kind: 3\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 80\n      m_Height: 80\n      m_Kind: 3\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 40\n      m_Height: 40\n      m_Kind: 3\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 87\n      m_Height: 87\n      m_Kind: 1\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 58\n      m_Height: 58\n      m_Kind: 1\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 29\n      m_Height: 29\n      m_Kind: 1\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 58\n      m_Height: 58\n      m_Kind: 1\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 29\n      m_Height: 29\n      m_Kind: 1\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 60\n      m_Height: 60\n      m_Kind: 2\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 40\n      m_Height: 40\n      m_Kind: 2\n      m_SubKind: iPhone\n    - m_Textures: []\n      m_Width: 40\n      m_Height: 40\n      m_Kind: 2\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 20\n      m_Height: 20\n      m_Kind: 2\n      m_SubKind: iPad\n    - m_Textures: []\n      m_Width: 1024\n      m_Height: 1024\n      m_Kind: 4\n      m_SubKind: App Store\n  - m_BuildTarget: Android\n    m_Icons:\n    - m_Textures: []\n      m_Width: 432\n      m_Height: 432\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 324\n      m_Height: 324\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 216\n      m_Height: 216\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 162\n      m_Height: 162\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 108\n      m_Height: 108\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 81\n      m_Height: 81\n      m_Kind: 2\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 192\n      m_Height: 192\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 144\n      m_Height: 144\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 96\n      m_Height: 96\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 72\n      m_Height: 72\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 48\n      m_Height: 48\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 36\n      m_Height: 36\n      m_Kind: 1\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 192\n      m_Height: 192\n      m_Kind: 0\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 144\n      m_Height: 144\n      m_Kind: 0\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 96\n      m_Height: 96\n      m_Kind: 0\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 72\n      m_Height: 72\n      m_Kind: 0\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 48\n      m_Height: 48\n      m_Kind: 0\n      m_SubKind: \n    - m_Textures: []\n      m_Width: 36\n      m_Height: 36\n      m_Kind: 0\n      m_SubKind: \n  m_BuildTargetBatching: []\n  m_BuildTargetGraphicsJobs: []\n  m_BuildTargetGraphicsJobMode: []\n  m_BuildTargetGraphicsAPIs:\n  - m_BuildTarget: iOSSupport\n    m_APIs: 10000000\n    m_Automatic: 1\n  - m_BuildTarget: AndroidPlayer\n    m_APIs: 0b00000008000000\n    m_Automatic: 0\n  m_BuildTargetVRSettings: []\n  openGLRequireES31: 0\n  openGLRequireES31AEP: 0\n  openGLRequireES32: 0\n  m_TemplateCustomTags: {}\n  mobileMTRendering:\n    Android: 1\n    iPhone: 1\n    tvOS: 1\n  m_BuildTargetGroupLightmapEncodingQuality: []\n  m_BuildTargetGroupLightmapSettings: []\n  m_BuildTargetNormalMapEncoding: []\n  m_BuildTargetDefaultTextureCompressionFormat: []\n  playModeTestRunnerEnabled: 0\n  runPlayModeTestAsEditModeTest: 0\n  actionOnDotNetUnhandledException: 1\n  enableInternalProfiler: 0\n  logObjCUncaughtExceptions: 1\n  enableCrashReportAPI: 0\n  cameraUsageDescription: \n  locationUsageDescription: \n  microphoneUsageDescription: \n  bluetoothUsageDescription: \n  switchNMETAOverride: \n  switchNetLibKey: \n  switchSocketMemoryPoolSize: 6144\n  switchSocketAllocatorPoolSize: 128\n  switchSocketConcurrencyLimit: 14\n  switchScreenResolutionBehavior: 2\n  switchUseCPUProfiler: 0\n  switchUseGOLDLinker: 0\n  switchLTOSetting: 0\n  switchApplicationID: 0x01004b9000490000\n  switchNSODependencies: \n  switchTitleNames_0: \n  switchTitleNames_1: \n  switchTitleNames_2: \n  switchTitleNames_3: \n  switchTitleNames_4: \n  switchTitleNames_5: \n  switchTitleNames_6: \n  switchTitleNames_7: \n  switchTitleNames_8: \n  switchTitleNames_9: \n  switchTitleNames_10: \n  switchTitleNames_11: \n  switchTitleNames_12: \n  switchTitleNames_13: \n  switchTitleNames_14: \n  switchTitleNames_15: \n  switchPublisherNames_0: \n  switchPublisherNames_1: \n  switchPublisherNames_2: \n  switchPublisherNames_3: \n  switchPublisherNames_4: \n  switchPublisherNames_5: \n  switchPublisherNames_6: \n  switchPublisherNames_7: \n  switchPublisherNames_8: \n  switchPublisherNames_9: \n  switchPublisherNames_10: \n  switchPublisherNames_11: \n  switchPublisherNames_12: \n  switchPublisherNames_13: \n  switchPublisherNames_14: \n  switchPublisherNames_15: \n  switchIcons_0: {fileID: 0}\n  switchIcons_1: {fileID: 0}\n  switchIcons_2: {fileID: 0}\n  switchIcons_3: {fileID: 0}\n  switchIcons_4: {fileID: 0}\n  switchIcons_5: {fileID: 0}\n  switchIcons_6: {fileID: 0}\n  switchIcons_7: {fileID: 0}\n  switchIcons_8: {fileID: 0}\n  switchIcons_9: {fileID: 0}\n  switchIcons_10: {fileID: 0}\n  switchIcons_11: {fileID: 0}\n  switchIcons_12: {fileID: 0}\n  switchIcons_13: {fileID: 0}\n  switchIcons_14: {fileID: 0}\n  switchIcons_15: {fileID: 0}\n  switchSmallIcons_0: {fileID: 0}\n  switchSmallIcons_1: {fileID: 0}\n  switchSmallIcons_2: {fileID: 0}\n  switchSmallIcons_3: {fileID: 0}\n  switchSmallIcons_4: {fileID: 0}\n  switchSmallIcons_5: {fileID: 0}\n  switchSmallIcons_6: {fileID: 0}\n  switchSmallIcons_7: {fileID: 0}\n  switchSmallIcons_8: {fileID: 0}\n  switchSmallIcons_9: {fileID: 0}\n  switchSmallIcons_10: {fileID: 0}\n  switchSmallIcons_11: {fileID: 0}\n  switchSmallIcons_12: {fileID: 0}\n  switchSmallIcons_13: {fileID: 0}\n  switchSmallIcons_14: {fileID: 0}\n  switchSmallIcons_15: {fileID: 0}\n  switchManualHTML: \n  switchAccessibleURLs: \n  switchLegalInformation: \n  switchMainThreadStackSize: 1048576\n  switchPresenceGroupId: \n  switchLogoHandling: 0\n  switchReleaseVersion: 0\n  switchDisplayVersion: 1.0.0\n  switchStartupUserAccount: 0\n  switchTouchScreenUsage: 0\n  switchSupportedLanguagesMask: 0\n  switchLogoType: 0\n  switchApplicationErrorCodeCategory: \n  switchUserAccountSaveDataSize: 0\n  switchUserAccountSaveDataJournalSize: 0\n  switchApplicationAttribute: 0\n  switchCardSpecSize: -1\n  switchCardSpecClock: -1\n  switchRatingsMask: 0\n  switchRatingsInt_0: 0\n  switchRatingsInt_1: 0\n  switchRatingsInt_2: 0\n  switchRatingsInt_3: 0\n  switchRatingsInt_4: 0\n  switchRatingsInt_5: 0\n  switchRatingsInt_6: 0\n  switchRatingsInt_7: 0\n  switchRatingsInt_8: 0\n  switchRatingsInt_9: 0\n  switchRatingsInt_10: 0\n  switchRatingsInt_11: 0\n  switchRatingsInt_12: 0\n  switchLocalCommunicationIds_0: \n  switchLocalCommunicationIds_1: \n  switchLocalCommunicationIds_2: \n  switchLocalCommunicationIds_3: \n  switchLocalCommunicationIds_4: \n  switchLocalCommunicationIds_5: \n  switchLocalCommunicationIds_6: \n  switchLocalCommunicationIds_7: \n  switchParentalControl: 0\n  switchAllowsScreenshot: 1\n  switchAllowsVideoCapturing: 1\n  switchAllowsRuntimeAddOnContentInstall: 0\n  switchDataLossConfirmation: 0\n  switchUserAccountLockEnabled: 0\n  switchSystemResourceMemory: 16777216\n  switchSupportedNpadStyles: 22\n  switchNativeFsCacheSize: 32\n  switchIsHoldTypeHorizontal: 0\n  switchSupportedNpadCount: 8\n  switchSocketConfigEnabled: 0\n  switchTcpInitialSendBufferSize: 32\n  switchTcpInitialReceiveBufferSize: 64\n  switchTcpAutoSendBufferSizeMax: 256\n  switchTcpAutoReceiveBufferSizeMax: 256\n  switchUdpSendBufferSize: 9\n  switchUdpReceiveBufferSize: 42\n  switchSocketBufferEfficiency: 4\n  switchSocketInitializeEnabled: 1\n  switchNetworkInterfaceManagerInitializeEnabled: 1\n  switchPlayerConnectionEnabled: 1\n  switchUseNewStyleFilepaths: 0\n  switchUseMicroSleepForYield: 1\n  switchEnableRamDiskSupport: 0\n  switchMicroSleepForYieldTime: 25\n  switchRamDiskSpaceSize: 12\n  ps4NPAgeRating: 12\n  ps4NPTitleSecret: \n  ps4NPTrophyPackPath: \n  ps4ParentalLevel: 11\n  ps4ContentID: ED1633-NPXX51362_00-0000000000000000\n  ps4Category: 0\n  ps4MasterVersion: 01.00\n  ps4AppVersion: 01.00\n  ps4AppType: 0\n  ps4ParamSfxPath: \n  ps4VideoOutPixelFormat: 0\n  ps4VideoOutInitialWidth: 1920\n  ps4VideoOutBaseModeInitialWidth: 1920\n  ps4VideoOutReprojectionRate: 60\n  ps4PronunciationXMLPath: \n  ps4PronunciationSIGPath: \n  ps4BackgroundImagePath: \n  ps4StartupImagePath: \n  ps4StartupImagesFolder: \n  ps4IconImagesFolder: \n  ps4SaveDataImagePath: \n  ps4SdkOverride: \n  ps4BGMPath: \n  ps4ShareFilePath: \n  ps4ShareOverlayImagePath: \n  ps4PrivacyGuardImagePath: \n  ps4ExtraSceSysFile: \n  ps4NPtitleDatPath: \n  ps4RemotePlayKeyAssignment: -1\n  ps4RemotePlayKeyMappingDir: \n  ps4PlayTogetherPlayerCount: 0\n  ps4EnterButtonAssignment: 2\n  ps4ApplicationParam1: 0\n  ps4ApplicationParam2: 0\n  ps4ApplicationParam3: 0\n  ps4ApplicationParam4: 0\n  ps4DownloadDataSize: 0\n  ps4GarlicHeapSize: 2048\n  ps4ProGarlicHeapSize: 2560\n  playerPrefsMaxSize: 32768\n  ps4Passcode: N2qmWqBlQ9wQj99nsQzldVI5ZuGXbEWR\n  ps4pnSessions: 1\n  ps4pnPresence: 1\n  ps4pnFriends: 1\n  ps4pnGameCustomData: 1\n  playerPrefsSupport: 0\n  enableApplicationExit: 0\n  resetTempFolder: 1\n  restrictedAudioUsageRights: 0\n  ps4UseResolutionFallback: 0\n  ps4ReprojectionSupport: 0\n  ps4UseAudio3dBackend: 0\n  ps4UseLowGarlicFragmentationMode: 1\n  ps4SocialScreenEnabled: 0\n  ps4ScriptOptimizationLevel: 2\n  ps4Audio3dVirtualSpeakerCount: 14\n  ps4attribCpuUsage: 0\n  ps4PatchPkgPath: \n  ps4PatchLatestPkgPath: \n  ps4PatchChangeinfoPath: \n  ps4PatchDayOne: 0\n  ps4attribUserManagement: 0\n  ps4attribMoveSupport: 0\n  ps4attrib3DSupport: 0\n  ps4attribShareSupport: 0\n  ps4attribExclusiveVR: 0\n  ps4disableAutoHideSplash: 0\n  ps4videoRecordingFeaturesUsed: 0\n  ps4contentSearchFeaturesUsed: 0\n  ps4CompatibilityPS5: 0\n  ps4AllowPS5Detection: 0\n  ps4GPU800MHz: 1\n  ps4attribEyeToEyeDistanceSettingVR: 0\n  ps4IncludedModules: []\n  ps4attribVROutputEnabled: 0\n  monoEnv: \n  splashScreenBackgroundSourceLandscape: {fileID: 0}\n  splashScreenBackgroundSourcePortrait: {fileID: 0}\n  blurSplashScreenBackground: 1\n  spritePackerPolicy: \n  webGLMemorySize: 32\n  webGLExceptionSupport: 1\n  webGLNameFilesAsHashes: 0\n  webGLDataCaching: 1\n  webGLDebugSymbols: 0\n  webGLEmscriptenArgs: \n  webGLModulesDirectory: \n  webGLTemplate: APPLICATION:Default\n  webGLAnalyzeBuildSize: 0\n  webGLUseEmbeddedResources: 0\n  webGLCompressionFormat: 0\n  webGLWasmArithmeticExceptions: 0\n  webGLLinkerTarget: 1\n  webGLThreadsSupport: 0\n  webGLDecompressionFallback: 0\n  scriptingDefineSymbols: {}\n  additionalCompilerArguments: {}\n  platformArchitecture: {}\n  scriptingBackend: {}\n  il2cppCompilerConfiguration: {}\n  managedStrippingLevel: {}\n  incrementalIl2cppBuild: {}\n  suppressCommonWarnings: 1\n  allowUnsafeCode: 0\n  useDeterministicCompilation: 1\n  enableRoslynAnalyzers: 1\n  additionalIl2CppArgs: \n  scriptingRuntimeVersion: 1\n  gcIncremental: 0\n  assemblyVersionValidation: 1\n  gcWBarrierValidation: 0\n  apiCompatibilityLevelPerPlatform: {}\n  m_RenderingPath: 1\n  m_MobileRenderingPath: 1\n  metroPackageName: appsflyer-unity-plugin\n  metroPackageVersion: \n  metroCertificatePath: \n  metroCertificatePassword: \n  metroCertificateSubject: \n  metroCertificateIssuer: \n  metroCertificateNotAfter: 0000000000000000\n  metroApplicationDescription: appsflyer-unity-plugin\n  wsaImages: {}\n  metroTileShortName: \n  metroTileShowName: 0\n  metroMediumTileShowName: 0\n  metroLargeTileShowName: 0\n  metroWideTileShowName: 0\n  metroSupportStreamingInstall: 0\n  metroLastRequiredScene: 0\n  metroDefaultTileSize: 1\n  metroTileForegroundText: 2\n  metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}\n  metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,\n    a: 1}\n  metroSplashScreenUseBackgroundColor: 0\n  platformCapabilities: {}\n  metroTargetDeviceFamilies: {}\n  metroFTAName: \n  metroFTAFileTypes: []\n  metroProtocolName: \n  vcxProjDefaultLanguage: \n  XboxOneProductId: \n  XboxOneUpdateKey: \n  XboxOneSandboxId: \n  XboxOneContentId: \n  XboxOneTitleId: \n  XboxOneSCId: \n  XboxOneGameOsOverridePath: \n  XboxOnePackagingOverridePath: \n  XboxOneAppManifestOverridePath: \n  XboxOneVersion: 1.0.0.0\n  XboxOnePackageEncryption: 0\n  XboxOnePackageUpdateGranularity: 2\n  XboxOneDescription: \n  XboxOneLanguage:\n  - enus\n  XboxOneCapability: []\n  XboxOneGameRating: {}\n  XboxOneIsContentPackage: 0\n  XboxOneEnhancedXboxCompatibilityMode: 0\n  XboxOneEnableGPUVariability: 1\n  XboxOneSockets: {}\n  XboxOneSplashScreen: {fileID: 0}\n  XboxOneAllowedProductIds: []\n  XboxOnePersistentLocalStorageSize: 0\n  XboxOneXTitleMemory: 8\n  XboxOneOverrideIdentityName: \n  XboxOneOverrideIdentityPublisher: \n  vrEditorSettings: {}\n  cloudServicesEnabled: {}\n  luminIcon:\n    m_Name: \n    m_ModelFolderPath: \n    m_PortalFolderPath: \n  luminCert:\n    m_CertPath: \n    m_SignPackage: 1\n  luminIsChannelApp: 0\n  luminVersion:\n    m_VersionCode: 1\n    m_VersionName: \n  apiCompatibilityLevel: 6\n  activeInputHandler: 0\n  cloudProjectId: \n  framebufferDepthMemorylessMode: 0\n  qualitySettingsNames: []\n  projectName: \n  organizationId: \n  cloudEnabled: 0\n  legacyClampBlendShapeWeights: 0\n  playerDataPath: \n  forceSRGBBlit: 1\n  virtualTexturingSupportEnabled: 0\n"
  },
  {
    "path": "ProjectSettings/ProjectVersion.txt",
    "content": "m_EditorVersion: 2020.3.41f1\nm_EditorVersionWithRevision: 2020.3.41f1 (7c19dc9acfda)\n"
  },
  {
    "path": "ProjectSettings/QualitySettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!47 &1\nQualitySettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 5\n  m_CurrentQuality: 5\n  m_QualitySettings:\n  - serializedVersion: 2\n    name: Very Low\n    pixelLightCount: 0\n    shadows: 0\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 15\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 0\n    skinWeights: 1\n    textureQuality: 1\n    anisotropicTextures: 0\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    realtimeReflectionProbes: 0\n    billboardsFaceCameraPosition: 0\n    vSyncCount: 0\n    lodBias: 0.3\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 4\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Low\n    pixelLightCount: 0\n    shadows: 0\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 20\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 0\n    skinWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 0\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    realtimeReflectionProbes: 0\n    billboardsFaceCameraPosition: 0\n    vSyncCount: 0\n    lodBias: 0.4\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 16\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Medium\n    pixelLightCount: 1\n    shadows: 1\n    shadowResolution: 0\n    shadowProjection: 1\n    shadowCascades: 1\n    shadowDistance: 20\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 0\n    skinWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 1\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 0\n    realtimeReflectionProbes: 0\n    billboardsFaceCameraPosition: 0\n    vSyncCount: 1\n    lodBias: 0.7\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 64\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: High\n    pixelLightCount: 2\n    shadows: 2\n    shadowResolution: 1\n    shadowProjection: 1\n    shadowCascades: 2\n    shadowDistance: 40\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 1\n    skinWeights: 2\n    textureQuality: 0\n    anisotropicTextures: 1\n    antiAliasing: 0\n    softParticles: 0\n    softVegetation: 1\n    realtimeReflectionProbes: 1\n    billboardsFaceCameraPosition: 1\n    vSyncCount: 1\n    lodBias: 1\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 256\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Very High\n    pixelLightCount: 3\n    shadows: 2\n    shadowResolution: 2\n    shadowProjection: 1\n    shadowCascades: 2\n    shadowDistance: 70\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 1\n    skinWeights: 4\n    textureQuality: 0\n    anisotropicTextures: 2\n    antiAliasing: 2\n    softParticles: 1\n    softVegetation: 1\n    realtimeReflectionProbes: 1\n    billboardsFaceCameraPosition: 1\n    vSyncCount: 1\n    lodBias: 1.5\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 1024\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  - serializedVersion: 2\n    name: Ultra\n    pixelLightCount: 4\n    shadows: 2\n    shadowResolution: 2\n    shadowProjection: 1\n    shadowCascades: 4\n    shadowDistance: 150\n    shadowNearPlaneOffset: 3\n    shadowCascade2Split: 0.33333334\n    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}\n    shadowmaskMode: 1\n    skinWeights: 255\n    textureQuality: 0\n    anisotropicTextures: 2\n    antiAliasing: 2\n    softParticles: 1\n    softVegetation: 1\n    realtimeReflectionProbes: 1\n    billboardsFaceCameraPosition: 1\n    vSyncCount: 1\n    lodBias: 2\n    maximumLODLevel: 0\n    streamingMipmapsActive: 0\n    streamingMipmapsAddAllCameras: 1\n    streamingMipmapsMemoryBudget: 512\n    streamingMipmapsRenderersPerFrame: 512\n    streamingMipmapsMaxLevelReduction: 2\n    streamingMipmapsMaxFileIORequests: 1024\n    particleRaycastBudget: 4096\n    asyncUploadTimeSlice: 2\n    asyncUploadBufferSize: 16\n    asyncUploadPersistentBuffer: 1\n    resolutionScalingFixedDPIFactor: 1\n    customRenderPipeline: {fileID: 0}\n    excludedTargetPlatforms: []\n  m_PerPlatformDefaultQuality:\n    Android: 2\n    CloudRendering: 5\n    GameCoreScarlett: 5\n    GameCoreXboxOne: 5\n    Lumin: 5\n    Nintendo Switch: 5\n    PS4: 5\n    PS5: 5\n    Stadia: 5\n    Standalone: 5\n    WebGL: 3\n    Windows Store Apps: 5\n    XboxOne: 5\n    iPhone: 2\n    tvOS: 2\n"
  },
  {
    "path": "ProjectSettings/TagManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!78 &1\nTagManager:\n  serializedVersion: 2\n  tags: []\n  layers:\n  - Default\n  - TransparentFX\n  - Ignore Raycast\n  - \n  - Water\n  - UI\n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  - \n  m_SortingLayers:\n  - name: Default\n    uniqueID: 0\n    locked: 0\n"
  },
  {
    "path": "ProjectSettings/TimeManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!5 &1\nTimeManager:\n  m_ObjectHideFlags: 0\n  Fixed Timestep: 0.02\n  Maximum Allowed Timestep: 0.33333334\n  m_TimeScale: 1\n  Maximum Particle Timestep: 0.03\n"
  },
  {
    "path": "ProjectSettings/UnityConnectSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!310 &1\nUnityConnectSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 1\n  m_Enabled: 0\n  m_TestMode: 0\n  m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events\n  m_EventUrl: https://cdp.cloud.unity3d.com/v1/events\n  m_ConfigUrl: https://config.uca.cloud.unity3d.com\n  m_TestInitMode: 0\n  CrashReportingSettings:\n    m_EventUrl: https://perf-events.cloud.unity3d.com\n    m_Enabled: 0\n    m_LogBufferSize: 10\n    m_CaptureEditorExceptions: 1\n  UnityPurchasingSettings:\n    m_Enabled: 0\n    m_TestMode: 0\n  UnityAnalyticsSettings:\n    m_Enabled: 0\n    m_TestMode: 0\n    m_InitializeOnStartup: 1\n  UnityAdsSettings:\n    m_Enabled: 0\n    m_InitializeOnStartup: 1\n    m_TestMode: 0\n    m_IosGameId: \n    m_AndroidGameId: \n    m_GameIds: {}\n    m_GameId: \n  PerformanceReportingSettings:\n    m_Enabled: 0\n"
  },
  {
    "path": "ProjectSettings/VFXManager.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!937362698 &1\nVFXManager:\n  m_ObjectHideFlags: 0\n  m_IndirectShader: {fileID: 0}\n  m_CopyBufferShader: {fileID: 0}\n  m_SortShader: {fileID: 0}\n  m_StripUpdateShader: {fileID: 0}\n  m_RenderPipeSettingsPath: \n  m_FixedTimeStep: 0.016666668\n  m_MaxDeltaTime: 0.05\n"
  },
  {
    "path": "ProjectSettings/VersionControlSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!890905787 &1\nVersionControlSettings:\n  m_ObjectHideFlags: 0\n  m_Mode: Visible Meta Files\n  m_CollabEditorSettings:\n    inProgressEnabled: 1\n"
  },
  {
    "path": "ProjectSettings/XRSettings.asset",
    "content": "{\n    \"m_SettingKeys\": [\n        \"VR Device Disabled\",\n        \"VR Device User Alert\"\n    ],\n    \"m_SettingValues\": [\n        \"False\",\n        \"False\"\n    ]\n}"
  },
  {
    "path": "README.md",
    "content": "<img src=\"https://massets.appsflyer.com/wp-content/uploads/2018/06/20092440/static-ziv_1TP.png\"  width=\"400\" >\n\n# appsflyer-unity-plugin\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![GitHub tag](https://img.shields.io/github/v/release/AppsFlyerSDK/appsflyer-unity-plugin)](https://img.shields.io/github/v/release/AppsFlyerSDK/appsflyer-unity-plugin)\n[![Unit tests](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/actions/workflows/main.yml/badge.svg)](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/actions/workflows/main.yml)\n[![check packages](https://github.com/af-margot/appsflyer-unity-plugin-beta/actions/workflows/checksums_files.yml/badge.svg)](https://github.com/af-margot/appsflyer-unity-plugin-beta/actions/workflows/checksums_files.yml)\n\n\n🛠 In order for us to provide optimal support, please contact AppsFlyer support through the Customer Assistant Chatbot for assistance with troubleshooting issues or product guidance. </br>\nTo do so, please follow [this article](https://support.appsflyer.com/hc/en-us/articles/23583984402193-Using-the-Customer-Assistant-Chatbot)\n\n\n## 📖 The Unity documentation also be found [here](https://dev.appsflyer.com/hc/docs/unity-plugin)\n\n### <a id=\"plugin-build-for\"> This plugin is built for\n\n- Android AppsFlyer SDK v6.17.6\n- Android Purchase Connector 2.2.0\n- iOS AppsFlyer SDK v6.17.9\n- iOS Purchase Connector 6.17.9\n---\n## 📌 Important: Two Versions of Unity Plugin v6.17.9\n\nWe have released **two** versions of the AppsFlyer Unity plugin to support teams at different stages of migrating to **Google Play Billing Library v8.0.0**.\n\n### Option A — `v6.17.91` (Billing Library v8) ← Latest\n- **What's included:** Support for **Google Play Billing Library 8.0.0** on Android (Android Purchase Connector version - 2.2.0).\n- **Impact:** This version may introduce **breaking changes** for apps that have **not yet migrated** to the Billing v8 APIs.\n- **Unity IAP requirement:** If you choose this option, update **Unity IAP (`com.unity.purchasing`) to version 5.0.0 or newer** (we recommend the latest 5.x). Unity IAP 4.x does **not** include Billing v8.\n\n### Option B — `v6.17.90` (Billing Library v7)\n- **Purpose:** For developers **not ready** to adopt Billing v8.\n- **Bundled SDKs:** **iOS SDK 6.17.9** and **Android SDK 6.17.6**.\n- **Android Purchase Connector:** Version 2.2.0\n- **Impact:** Lets you update the AppsFlyer SDKs without changing your existing (pre‑v8) billing integration.\n\n---  \n## <a id=\"new-in-6171\">     🎉 New in 6.17.1 - Purchase Connector Integration \n- Starting from version 6.17.1, the **Purchase Connector is now integrated directly into the main AppsFlyer Unity plugin**. You no longer need to download, import, or maintain a separate Purchase Connector package.\n- If you were previously using the standalone Purchase Connector from a separate repository, simply remove any references to `using AppsFlyerConnector;` from your codebase, as its functionality is now included in the main plugin under the `AppsFlyerSDK` namespace.\n- The Purchase Connector now supports **StoreKit 2** for iOS 15+ alongside the existing StoreKit 1 support.\n- For detailed migration instructions and new features, see our [Purchase Connector documentation](/docs/purchase-connector.md).\n\n---\n## <a id=\"breaking-changes-6175\">     ❗❗ Breaking changes when updating to 6.17.5 ❗❗\n- **In-App Purchase Validation API Changes**: The `validateAndSendInAppPurchase` method signatures have been updated for better type safety and cleaner code.\n- **V2 Methods (Recommended)**: New overloads using structured data classes (`AFPurchaseDetailsAndroid`/`AFSDKPurchaseDetailsIOS`) are now the recommended approach.\n- **Legacy Methods (Deprecated)**: The old string-based parameter methods are now deprecated but maintained for backward compatibility.\n- **Migration Required**: If you're using the old `validateAndSendInAppPurchase` methods, consider migrating to the V2 versions for better maintainability.\n- For detailed API documentation and migration examples, see our [API reference](/docs/API.md).\n\n---  \n## <a id=\"breaking-changes\">     ❗❗ Breaking changes when updating to 6.12.20 ❗❗\n- Starting from version 6.12.20, we have changed the way we distribute the plugin via UPM. The UPM branches will no longer hold a dependency for `com.google.external-dependency-manager` as it was proved to cause issues in different versions of Unity - to be clear, this dependency is still required to utilize our plugin, we just can't distribute the plugin with it in UPM form as the EDM4U dependency is [not available via UPM for quite a while already](https://github.com/googlesamples/unity-jar-resolver/issues/434#issuecomment-827028132) but is still available via `.unitypackage` or `.tgz` files, if you use UPM to fetch our plugin - [please download a suitable version of EDM4U](https://github.com/googlesamples/unity-jar-resolver) so you will be able to resolve the dependencies, or opt for [an installation without EDM4U](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/docs/Installation.md#installation-without-unity-jar-resolver).\n---  \n\n## <a id=\"breaking-changes\">     ❗❗ Breaking changes when updating to 6.6.0 ❗❗\n- Starting version 6.6.0, there is no more need to differentiate between iOS and Android APIs. All APIs must be called with `AppsFlyer` class (even if the API is only iOS or Android).\n- Please take into consideration that since version 6.6.0, most of the APIs require `initSDK` to be called prior to using them, and since version 6.10.10 only a handful of APIs will properly work when called prior to initialization: `setIsDebug`, `setCurrencyCode`, `setHost`, `disableSKAdNetwork`.\n\nExample:\n\nBefore 6.6.0:\n```c#\n#if UNITY_IOS && !UNITY_EDITOR\n    AppsFlyeriOS.waitForATTUserAuthorizationWithTimeoutInterval(60);\n#endif\n```\n---\n\nAfter 6.6.0:\n```c#\n#if UNITY_IOS && !UNITY_EDITOR\n    AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(60);\n#endif\n```\n---\n\n## <a id=\"strict-mode\"> Strict Mode\nThe plugin supports a Strict Mode which completely removes the IDFA collection functionality and AdSupport framework dependencies.\nUse the Strict Mode when developing apps for kids, for example.\nMore information about how to install the Strict Mode is available [here](/docs/Installation.md).\n\n\n### <a id=\"init-sdk-deeplink\"> AD_ID permission for Android\n\nIn v6.8.0 of the AppsFlyer SDK, we added the normal permission com.google.android.gms.permission.AD_ID to the SDK's AndroidManifest, to allow the SDK to collect the Android Advertising ID on apps targeting API 33. If your app is targeting children, you need to revoke this permission to comply with Google's Data policy. You can read more about it [here](https://dev.appsflyer.com/hc/docs/install-android-sdk#the-ad_id-permission).\n\n\n\n ---\n## <a id=\"plugin-build-for\"> 🚀 Getting Started\n- [Installation](/docs/Installation.md)\n- [Integration](/docs/BasicIntegration.md)\n- [Test integration](/docs/Testing.md)\n- [In-app events](/docs/InAppEvents.md)\n- [Send Consent for DMA Compliance](/docs/DMAConsent.md)\n- [Uninstall measurement](/docs/UninstallMeasurement.md)\n## <a id=\"plugin-build-for\"> 💰 Purchase Connector\n- [Purchase Connector (ROI360)](/docs/purchase-connector.md)\n## <a id=\"plugin-build-for\"> 🔗 Deep Linking\n- [Integration](/docs/DeepLinkIntegrate.md)\n- [Unified Deep Link (UDL)](/docs/UnifiedDeepLink.md)\n- [User invite](/docs/UserInvite.md)\n## <a id=\"plugin-build-for\"> 🧪 Sample App\n- [ButterFlyer](https://github.com/AppsFlyerSDK/appsflyer-unity-sample-app)\n\n----  \n### [API reference](/docs/API.md)    \n### [Troubleshooting](/docs/Troubleshooting.md)\n\n\n\n"
  },
  {
    "path": "UserSettings/EditorUserSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!162 &1\nEditorUserSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 4\n  m_ConfigSettings:\n    vcSharedLogLevel:\n      value: 0d5e400f0650\n      flags: 0\n  m_VCAutomaticAdd: 1\n  m_VCDebugCom: 0\n  m_VCDebugCmd: 0\n  m_VCDebugOut: 0\n  m_SemanticMergeMode: 2\n  m_DesiredImportWorkerCount: 2\n  m_StandbyImportWorkerCount: 2\n  m_IdleImportWorkerShutdownDelay: 60000\n  m_VCShowFailedCheckout: 1\n  m_VCOverwriteFailedCheckoutAssets: 1\n  m_VCProjectOverlayIcons: 1\n  m_VCHierarchyOverlayIcons: 1\n  m_VCOtherOverlayIcons: 1\n  m_VCAllowAsyncUpdate: 1\n  m_ArtifactGarbageCollection: 1\n"
  },
  {
    "path": "UserSettings/Layouts/default-2021.dwlt",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!114 &1\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_PixelRect:\n    serializedVersion: 2\n    x: 0\n    y: 53\n    width: 1440\n    height: 847\n  m_ShowMode: 4\n  m_Title: Project\n  m_RootView: {fileID: 6}\n  m_MinSize: {x: 875, y: 300}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_Maximized: 0\n--- !u!114 &2\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 9}\n  - {fileID: 3}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 30\n    width: 1440\n    height: 797\n  m_MinSize: {x: 300, y: 200}\n  m_MaxSize: {x: 24288, y: 16192}\n  vertical: 0\n  controlID: 16\n--- !u!114 &3\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 1148\n    y: 0\n    width: 292\n    height: 797\n  m_MinSize: {x: 276, y: 71}\n  m_MaxSize: {x: 4001, y: 4021}\n  m_ActualView: {fileID: 14}\n  m_Panes:\n  - {fileID: 14}\n  m_Selected: 0\n  m_LastSelected: 0\n--- !u!114 &4\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 284\n    height: 482\n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_ActualView: {fileID: 15}\n  m_Panes:\n  - {fileID: 15}\n  m_Selected: 0\n  m_LastSelected: 0\n--- !u!114 &5\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: ProjectBrowser\n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 482\n    width: 1148\n    height: 315\n  m_MinSize: {x: 231, y: 271}\n  m_MaxSize: {x: 10001, y: 10021}\n  m_ActualView: {fileID: 13}\n  m_Panes:\n  - {fileID: 13}\n  - {fileID: 18}\n  m_Selected: 0\n  m_LastSelected: 1\n--- !u!114 &6\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 7}\n  - {fileID: 2}\n  - {fileID: 8}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1440\n    height: 847\n  m_MinSize: {x: 875, y: 300}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_UseTopView: 1\n  m_TopViewHeight: 30\n  m_UseBottomView: 1\n  m_BottomViewHeight: 20\n--- !u!114 &7\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1440\n    height: 30\n  m_MinSize: {x: 0, y: 0}\n  m_MaxSize: {x: 0, y: 0}\n  m_LastLoadedLayoutName: \n--- !u!114 &8\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 827\n    width: 1440\n    height: 20\n  m_MinSize: {x: 0, y: 0}\n  m_MaxSize: {x: 0, y: 0}\n--- !u!114 &9\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 10}\n  - {fileID: 5}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1148\n    height: 797\n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 16192, y: 16192}\n  vertical: 1\n  controlID: 17\n--- !u!114 &10\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 4}\n  - {fileID: 11}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1148\n    height: 482\n  m_MinSize: {x: 200, y: 100}\n  m_MaxSize: {x: 16192, y: 8096}\n  vertical: 0\n  controlID: 18\n--- !u!114 &11\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 284\n    y: 0\n    width: 864\n    height: 482\n  m_MinSize: {x: 202, y: 221}\n  m_MaxSize: {x: 4002, y: 4021}\n  m_ActualView: {fileID: 16}\n  m_Panes:\n  - {fileID: 16}\n  - {fileID: 17}\n  - {fileID: 12}\n  m_Selected: 0\n  m_LastSelected: 1\n--- !u!114 &12\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12111, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 400, y: 100}\n  m_MaxSize: {x: 2048, y: 2048}\n  m_TitleContent:\n    m_Text: Asset Store\n    m_Image: {fileID: -7444545952099596278, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 468\n    y: 181\n    width: 973\n    height: 501\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n--- !u!114 &13\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 230, y: 250}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_TitleContent:\n    m_Text: Project\n    m_Image: {fileID: -5179483145760003458, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 0\n    y: 565\n    width: 1147\n    height: 294\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n  m_SearchFilter:\n    m_NameFilter: \n    m_ClassNames: []\n    m_AssetLabels: []\n    m_AssetBundleNames: []\n    m_VersionControlStates: []\n    m_SoftLockControlStates: []\n    m_ReferencingInstanceIDs: \n    m_SceneHandles: \n    m_ShowAllHits: 0\n    m_SkipHidden: 0\n    m_SearchArea: 1\n    m_Folders:\n    - Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle\n    m_Globs: []\n    m_OriginalText: \n  m_ViewMode: 1\n  m_StartGridSize: 64\n  m_LastFolders:\n  - Assets/AppsFlyer/Mac/AppsFlyerBundle.bundle\n  m_LastFoldersGridSize: -1\n  m_LastProjectPath: /Users/margotguetta/Desktop/Projects/Plugin/Unity/appsflyer-unity-plugin\n  m_LockTracker:\n    m_IsLocked: 0\n  m_FolderTreeState:\n    scrollPos: {x: 0, y: 0}\n    m_SelectedIDs: 4e060000\n    m_LastClickedID: 1614\n    m_ExpandedIDs: 00000000ee5e0000f05e0000f25e00000e5f000000ca9a3bffffff7f\n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: Mac\n      m_OriginalName: Mac\n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 24334\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 0\n      m_IsRenamingFilename: 1\n      m_ClientGUIView: {fileID: 5}\n    m_SearchString: \n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n  m_AssetTreeState:\n    scrollPos: {x: 0, y: 0}\n    m_SelectedIDs: \n    m_LastClickedID: 0\n    m_ExpandedIDs: 00000000ee5e0000f05e0000f25e0000\n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: \n      m_OriginalName: \n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 0\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 11\n      m_IsRenamingFilename: 1\n      m_ClientGUIView: {fileID: 0}\n    m_SearchString: \n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n  m_ListAreaState:\n    m_SelectedInstanceIDs: \n    m_LastClickedInstanceID: 0\n    m_HadKeyboardFocusLastEvent: 0\n    m_ExpandedInstanceIDs: c6230000\n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: \n      m_OriginalName: \n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 0\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 11\n      m_IsRenamingFilename: 1\n      m_ClientGUIView: {fileID: 0}\n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n    m_NewAssetIndexInList: -1\n    m_ScrollPosition: {x: 0, y: 0}\n    m_GridSize: 64\n  m_SkipHiddenPackages: 0\n  m_DirectoriesAreaWidth: 115\n--- !u!114 &14\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 275, y: 50}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Inspector\n    m_Image: {fileID: -440750813802333266, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 1148\n    y: 83\n    width: 291\n    height: 776\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n  m_ObjectsLockedBeforeSerialization: []\n  m_InstanceIDsLockedBeforeSerialization: \n  m_PreviewResizer:\n    m_CachedPref: 160\n    m_ControlHash: -371814159\n    m_PrefName: Preview_InspectorPreview\n  m_LastInspectedObjectInstanceID: -1\n  m_LastVerticalScrollValue: 0\n  m_GlobalObjectId: \n  m_InspectorMode: 0\n  m_LockTracker:\n    m_IsLocked: 0\n  m_PreviewWindow: {fileID: 0}\n--- !u!114 &15\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Hierarchy\n    m_Image: {fileID: -3734745235275155857, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 0\n    y: 83\n    width: 283\n    height: 461\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n  m_SceneHierarchy:\n    m_TreeViewState:\n      scrollPos: {x: 0, y: 0}\n      m_SelectedIDs: 4e060000\n      m_LastClickedID: 0\n      m_ExpandedIDs: c6faffff\n      m_RenameOverlay:\n        m_UserAcceptedRename: 0\n        m_Name: \n        m_OriginalName: \n        m_EditFieldRect:\n          serializedVersion: 2\n          x: 0\n          y: 0\n          width: 0\n          height: 0\n        m_UserData: 0\n        m_IsWaitingForDelay: 0\n        m_IsRenaming: 0\n        m_OriginalEventType: 11\n        m_IsRenamingFilename: 0\n        m_ClientGUIView: {fileID: 0}\n      m_SearchString: \n    m_ExpandedScenes: []\n    m_CurrenRootInstanceID: 0\n    m_LockTracker:\n      m_IsLocked: 0\n    m_CurrentSortingName: TransformSorting\n  m_WindowGUID: 9a5ee93bb0e91428facd2b3497f49068\n--- !u!114 &16\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Scene\n    m_Image: {fileID: 8634526014445323508, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 284\n    y: 83\n    width: 862\n    height: 461\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData:\n    - dockPosition: 0\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 1\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: -98, y: -26}\n      snapCorner: 3\n      id: Tool Settings\n      index: 0\n      layout: 1\n    - dockPosition: 0\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 1\n      snapOffset: {x: -141, y: 149}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 1\n      id: unity-grid-and-snap-toolbar\n      index: 1\n      layout: 1\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 1\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: unity-scene-view-toolbar\n      index: 0\n      layout: 1\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 1\n      id: unity-search-toolbar\n      index: 1\n      layout: 1\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Open Tile Palette\n      index: 2\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Tilemap Focus\n      index: 3\n      layout: 4\n    - dockPosition: 0\n      containerId: overlay-container--left\n      floating: 0\n      collapsed: 0\n      displayed: 1\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: unity-transform-toolbar\n      index: 0\n      layout: 2\n    - dockPosition: 0\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 1\n      snapOffset: {x: 67.5, y: 86}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Orientation\n      index: 0\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Light Settings\n      index: 0\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Camera\n      index: 1\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Cloth Constraints\n      index: 2\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Cloth Collisions\n      index: 3\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Navmesh Display\n      index: 4\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Agent Display\n      index: 5\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Obstacle Display\n      index: 6\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Occlusion Culling\n      index: 7\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Physics Debugger\n      index: 8\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Scene Visibility\n      index: 9\n      layout: 4\n    - dockPosition: 1\n      containerId: overlay-container--right\n      floating: 0\n      collapsed: 0\n      displayed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      id: Scene View/Particles\n      index: 10\n      layout: 4\n  m_WindowGUID: 1acd90b02262845b2a933768b9dd2124\n  m_Gizmos: 1\n  m_OverrideSceneCullingMask: 6917529027641081856\n  m_SceneIsLit: 1\n  m_SceneLighting: 1\n  m_2DMode: 0\n  m_isRotationLocked: 0\n  m_PlayAudio: 0\n  m_AudioPlay: 0\n  m_Position:\n    m_Target: {x: 0, y: 0, z: 0}\n    speed: 2\n    m_Value: {x: 0, y: 0, z: 0}\n  m_RenderMode: 0\n  m_CameraMode:\n    drawMode: 0\n    name: Shaded\n    section: Shading Mode\n  m_ValidateTrueMetals: 0\n  m_DoValidateTrueMetals: 0\n  m_ExposureSliderValue: 0\n  m_SceneViewState:\n    m_AlwaysRefresh: 0\n    showFog: 1\n    showSkybox: 1\n    showFlares: 1\n    showImageEffects: 1\n    showParticleSystems: 1\n    showVisualEffectGraphs: 1\n    m_FxEnabled: 1\n  m_Grid:\n    xGrid:\n      m_Fade:\n        m_Target: 0\n        speed: 2\n        m_Value: 0\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 0, y: 0}\n    yGrid:\n      m_Fade:\n        m_Target: 1\n        speed: 2\n        m_Value: 1\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 1, y: 1}\n    zGrid:\n      m_Fade:\n        m_Target: 0\n        speed: 2\n        m_Value: 0\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 0, y: 0}\n    m_ShowGrid: 1\n    m_GridAxis: 1\n    m_gridOpacity: 0.5\n  m_Rotation:\n    m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}\n    speed: 2\n    m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}\n  m_Size:\n    m_Target: 10\n    speed: 2\n    m_Value: 10\n  m_Ortho:\n    m_Target: 0\n    speed: 2\n    m_Value: 0\n  m_CameraSettings:\n    m_Speed: 1\n    m_SpeedNormalized: 0.5\n    m_SpeedMin: 0.01\n    m_SpeedMax: 2\n    m_EasingEnabled: 1\n    m_EasingDuration: 0.4\n    m_AccelerationEnabled: 1\n    m_FieldOfViewHorizontalOrVertical: 60\n    m_NearClip: 0.03\n    m_FarClip: 10000\n    m_DynamicClip: 1\n    m_OcclusionCulling: 0\n  m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}\n  m_LastSceneViewOrtho: 0\n  m_ReplacementShader: {fileID: 0}\n  m_ReplacementString: \n  m_SceneVisActive: 1\n  m_LastLockedObject: {fileID: 0}\n  m_ViewIsLockedToObject: 0\n--- !u!114 &17\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Game\n    m_Image: {fileID: 4621777727084837110, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 507\n    y: 94\n    width: 1532\n    height: 790\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n  m_SerializedViewNames: []\n  m_SerializedViewValues: []\n  m_PlayModeViewName: GameView\n  m_ShowGizmos: 0\n  m_TargetDisplay: 0\n  m_ClearColor: {r: 0, g: 0, b: 0, a: 0}\n  m_TargetSize: {x: 3064, y: 1538}\n  m_TextureFilterMode: 0\n  m_TextureHideFlags: 61\n  m_RenderIMGUI: 0\n  m_EnterPlayModeBehavior: 0\n  m_UseMipMap: 0\n  m_VSyncEnabled: 0\n  m_Gizmos: 0\n  m_Stats: 0\n  m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000\n  m_ZoomArea:\n    m_HRangeLocked: 0\n    m_VRangeLocked: 0\n    hZoomLockedByDefault: 0\n    vZoomLockedByDefault: 0\n    m_HBaseRangeMin: -766\n    m_HBaseRangeMax: 766\n    m_VBaseRangeMin: -384.5\n    m_VBaseRangeMax: 384.5\n    m_HAllowExceedBaseRangeMin: 1\n    m_HAllowExceedBaseRangeMax: 1\n    m_VAllowExceedBaseRangeMin: 1\n    m_VAllowExceedBaseRangeMax: 1\n    m_ScaleWithWindow: 0\n    m_HSlider: 0\n    m_VSlider: 0\n    m_IgnoreScrollWheelUntilClicked: 0\n    m_EnableMouseInput: 1\n    m_EnableSliderZoomHorizontal: 0\n    m_EnableSliderZoomVertical: 0\n    m_UniformScale: 1\n    m_UpDirection: 1\n    m_DrawArea:\n      serializedVersion: 2\n      x: 0\n      y: 21\n      width: 1532\n      height: 769\n    m_Scale: {x: 1, y: 1}\n    m_Translation: {x: 766, y: 384.5}\n    m_MarginLeft: 0\n    m_MarginRight: 0\n    m_MarginTop: 0\n    m_MarginBottom: 0\n    m_LastShownAreaInsideMargins:\n      serializedVersion: 2\n      x: -766\n      y: -384.5\n      width: 1532\n      height: 769\n    m_MinimalGUI: 1\n  m_defaultScale: 1\n  m_LastWindowPixelSize: {x: 3064, y: 1580}\n  m_ClearInEditMode: 1\n  m_NoCameraWarning: 1\n  m_LowResolutionForAspectRatios: 00000000000000000000\n  m_XRRenderMode: 0\n  m_RenderTexture: {fileID: 0}\n--- !u!114 &18\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 100, y: 100}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Console\n    m_Image: {fileID: -4950941429401207979, guid: 0000000000000000d000000000000000, type: 0}\n    m_Tooltip: \n  m_Pos:\n    serializedVersion: 2\n    x: 0\n    y: 565\n    width: 1147\n    height: 294\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n"
  },
  {
    "path": "UserSettings/Layouts/default-6000.dwlt",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!114 &1\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_PixelRect:\n    serializedVersion: 2\n    x: 2250\n    y: 247\n    width: 1256\n    height: 724\n  m_ShowMode: 0\n  m_Title: Package Manager\n  m_RootView: {fileID: 4}\n  m_MinSize: {x: 748, y: 276}\n  m_MaxSize: {x: 4000, y: 4026}\n  m_Maximized: 0\n--- !u!114 &2\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_PixelRect:\n    serializedVersion: 2\n    x: 1792\n    y: -153\n    width: 2560\n    height: 1333\n  m_ShowMode: 4\n  m_Title: Project\n  m_RootView: {fileID: 9}\n  m_MinSize: {x: 875, y: 300}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_Maximized: 1\n--- !u!114 &3\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: PackageManagerWindow\n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1256\n    height: 724\n  m_MinSize: {x: 748, y: 276}\n  m_MaxSize: {x: 4000, y: 4026}\n  m_ActualView: {fileID: 15}\n  m_Panes:\n  - {fileID: 15}\n  m_Selected: 0\n  m_LastSelected: 0\n--- !u!114 &4\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 3}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 1256\n    height: 724\n  m_MinSize: {x: 748, y: 276}\n  m_MaxSize: {x: 4000, y: 4026}\n  vertical: 0\n  controlID: 14\n  draggingID: 0\n--- !u!114 &5\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 12}\n  - {fileID: 6}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 36\n    width: 2560\n    height: 1277\n  m_MinSize: {x: 300, y: 100}\n  m_MaxSize: {x: 24288, y: 16192}\n  vertical: 0\n  controlID: 50\n  draggingID: 0\n--- !u!114 &6\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 2039\n    y: 0\n    width: 521\n    height: 1277\n  m_MinSize: {x: 275, y: 50}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_ActualView: {fileID: 18}\n  m_Panes:\n  - {fileID: 18}\n  m_Selected: 0\n  m_LastSelected: 0\n--- !u!114 &7\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 504\n    height: 772\n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_ActualView: {fileID: 19}\n  m_Panes:\n  - {fileID: 19}\n  m_Selected: 0\n  m_LastSelected: 0\n--- !u!114 &8\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: ProjectBrowser\n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 772\n    width: 2039\n    height: 505\n  m_MinSize: {x: 231, y: 276}\n  m_MaxSize: {x: 10001, y: 10026}\n  m_ActualView: {fileID: 17}\n  m_Panes:\n  - {fileID: 17}\n  - {fileID: 22}\n  m_Selected: 0\n  m_LastSelected: 1\n--- !u!114 &9\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 10}\n  - {fileID: 5}\n  - {fileID: 11}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 2560\n    height: 1333\n  m_MinSize: {x: 875, y: 300}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_UseTopView: 1\n  m_TopViewHeight: 36\n  m_UseBottomView: 1\n  m_BottomViewHeight: 20\n--- !u!114 &10\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 2560\n    height: 36\n  m_MinSize: {x: 0, y: 0}\n  m_MaxSize: {x: 0, y: 0}\n  m_LastLoadedLayoutName: \n--- !u!114 &11\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 1313\n    width: 2560\n    height: 20\n  m_MinSize: {x: 0, y: 0}\n  m_MaxSize: {x: 0, y: 0}\n--- !u!114 &12\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 13}\n  - {fileID: 8}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 2039\n    height: 1277\n  m_MinSize: {x: 200, y: 100}\n  m_MaxSize: {x: 16192, y: 16192}\n  vertical: 1\n  controlID: 51\n  draggingID: 0\n--- !u!114 &13\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children:\n  - {fileID: 7}\n  - {fileID: 14}\n  m_Position:\n    serializedVersion: 2\n    x: 0\n    y: 0\n    width: 2039\n    height: 772\n  m_MinSize: {x: 200, y: 50}\n  m_MaxSize: {x: 16192, y: 8096}\n  vertical: 0\n  controlID: 42\n  draggingID: 0\n--- !u!114 &14\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_Children: []\n  m_Position:\n    serializedVersion: 2\n    x: 504\n    y: 0\n    width: 1535\n    height: 772\n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_ActualView: {fileID: 20}\n  m_Panes:\n  - {fileID: 20}\n  - {fileID: 21}\n  - {fileID: 16}\n  m_Selected: 0\n  m_LastSelected: 1\n--- !u!114 &15\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 13953, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 748, y: 250}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Package Manager\n    m_Image: {fileID: -2824328813065806953, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Package Manager\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 2250\n    y: 247\n    width: 1256\n    height: 698\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n--- !u!114 &16\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12111, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 400, y: 100}\n  m_MaxSize: {x: 2048, y: 2048}\n  m_TitleContent:\n    m_Text: Asset Store\n    m_Image: {fileID: -8693916549880196297, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Asset Store\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 468\n    y: 181\n    width: 973\n    height: 501\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n--- !u!114 &17\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 230, y: 250}\n  m_MaxSize: {x: 10000, y: 10000}\n  m_TitleContent:\n    m_Text: Project\n    m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Project\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 1792\n    y: 655\n    width: 2038\n    height: 479\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n  m_SearchFilter:\n    m_NameFilter: \n    m_ClassNames: []\n    m_AssetLabels: []\n    m_AssetBundleNames: []\n    m_ReferencingInstanceIDs: \n    m_SceneHandles: \n    m_ShowAllHits: 0\n    m_SkipHidden: 0\n    m_SearchArea: 1\n    m_Folders:\n    - Packages\n    m_Globs: []\n    m_ProductIds: \n    m_AnyWithAssetOrigin: 0\n    m_OriginalText: \n    m_ImportLogFlags: 0\n    m_FilterByTypeIntersection: 0\n  m_ViewMode: 1\n  m_StartGridSize: 64\n  m_LastFolders:\n  - Packages\n  m_LastFoldersGridSize: -1\n  m_LastProjectPath: /Users/veronicabelyakov/Applications/appsflyer-unity-plugin\n  m_LockTracker:\n    m_IsLocked: 0\n  m_FolderTreeState:\n    scrollPos: {x: 0, y: 0}\n    m_SelectedIDs: ffffff7f\n    m_LastClickedID: 2147483647\n    m_ExpandedIDs: 000000007049000000ca9a3bffffff7f\n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: \n      m_OriginalName: \n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 0\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 11\n      m_IsRenamingFilename: 1\n      m_TrimLeadingAndTrailingWhitespace: 0\n      m_ClientGUIView: {fileID: 8}\n    m_SearchString: \n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n  m_AssetTreeState:\n    scrollPos: {x: 0, y: 0}\n    m_SelectedIDs: \n    m_LastClickedID: 0\n    m_ExpandedIDs: \n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: \n      m_OriginalName: \n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 0\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 11\n      m_IsRenamingFilename: 1\n      m_TrimLeadingAndTrailingWhitespace: 0\n      m_ClientGUIView: {fileID: 0}\n    m_SearchString: \n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n  m_ListAreaState:\n    m_SelectedInstanceIDs: \n    m_LastClickedInstanceID: 0\n    m_HadKeyboardFocusLastEvent: 0\n    m_ExpandedInstanceIDs: c6230000\n    m_RenameOverlay:\n      m_UserAcceptedRename: 0\n      m_Name: \n      m_OriginalName: \n      m_EditFieldRect:\n        serializedVersion: 2\n        x: 0\n        y: 0\n        width: 0\n        height: 0\n      m_UserData: 0\n      m_IsWaitingForDelay: 0\n      m_IsRenaming: 0\n      m_OriginalEventType: 11\n      m_IsRenamingFilename: 1\n      m_TrimLeadingAndTrailingWhitespace: 0\n      m_ClientGUIView: {fileID: 0}\n    m_CreateAssetUtility:\n      m_EndAction: {fileID: 0}\n      m_InstanceID: 0\n      m_Path: \n      m_Icon: {fileID: 0}\n      m_ResourceFile: \n    m_NewAssetIndexInList: -1\n    m_ScrollPosition: {x: 0, y: 0}\n    m_GridSize: 64\n  m_SkipHiddenPackages: 0\n  m_DirectoriesAreaWidth: 246\n--- !u!114 &18\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 275, y: 50}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Inspector\n    m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Inspector\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 3831\n    y: -117\n    width: 520\n    height: 1251\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n  m_ObjectsLockedBeforeSerialization: []\n  m_InstanceIDsLockedBeforeSerialization: \n  m_PreviewResizer:\n    m_CachedPref: 160\n    m_ControlHash: -371814159\n    m_PrefName: Preview_InspectorPreview\n  m_LastInspectedObjectInstanceID: -1\n  m_LastVerticalScrollValue: 0\n  m_GlobalObjectId: \n  m_InspectorMode: 0\n  m_LockTracker:\n    m_IsLocked: 0\n  m_PreviewWindow: {fileID: 0}\n--- !u!114 &19\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Hierarchy\n    m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Hierarchy\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 1792\n    y: -117\n    width: 503\n    height: 746\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n  m_SceneHierarchy:\n    m_TreeViewState:\n      scrollPos: {x: 0, y: 0}\n      m_SelectedIDs: \n      m_LastClickedID: 0\n      m_ExpandedIDs: b6f1ffff\n      m_RenameOverlay:\n        m_UserAcceptedRename: 0\n        m_Name: \n        m_OriginalName: \n        m_EditFieldRect:\n          serializedVersion: 2\n          x: 0\n          y: 0\n          width: 0\n          height: 0\n        m_UserData: 0\n        m_IsWaitingForDelay: 0\n        m_IsRenaming: 0\n        m_OriginalEventType: 11\n        m_IsRenamingFilename: 0\n        m_TrimLeadingAndTrailingWhitespace: 0\n        m_ClientGUIView: {fileID: 0}\n      m_SearchString: \n    m_ExpandedScenes: []\n    m_CurrenRootInstanceID: 0\n    m_LockTracker:\n      m_IsLocked: 0\n    m_CurrentSortingName: TransformSorting\n  m_WindowGUID: 9a5ee93bb0e91428facd2b3497f49068\n--- !u!114 &20\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Scene\n    m_Image: {fileID: 2593428753322112591, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Scene\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 2296\n    y: -117\n    width: 1533\n    height: 746\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData:\n    - dockPosition: 0\n      containerId: overlay-toolbar__top\n      displayed: 1\n      id: Tool Settings\n      index: 0\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":-24.0,\"y\":-24.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":3,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: -24, y: -24}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 3\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-toolbar__top\n      displayed: 1\n      id: unity-grid-and-snap-toolbar\n      index: 1\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":-141.0,\"y\":149.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":1,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: -141, y: 149}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 1\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      displayed: 1\n      id: unity-scene-view-toolbar\n      index: 0\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":24.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 24, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      displayed: 0\n      id: unity-search-toolbar\n      index: 1\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":-24.0,\"y\":0.0},\"m_FloatingSnapCorner\":1,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: -24, y: 0}\n      snapCorner: 1\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      displayed: 0\n      id: Scene View/Open Tile Palette\n      index: 2\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      displayed: 0\n      id: Scene View/Tilemap Focus\n      index: 3\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-container--left\n      displayed: 1\n      id: unity-transform-toolbar\n      index: 0\n      contents: '{\"m_Layout\":2,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":24.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 24, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 2\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-container--right\n      displayed: 1\n      id: Orientation\n      index: 0\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":67.5,\"y\":86.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 67.5, y: 86}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Light Settings\n      index: 0\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Camera\n      index: 1\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Cloth Constraints\n      index: 1\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Cloth Collisions\n      index: 2\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Navmesh Display\n      index: 4\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Agent Display\n      index: 5\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Obstacle Display\n      index: 6\n      contents: \n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Occlusion Culling\n      index: 3\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Physics Debugger\n      index: 4\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Scene Visibility\n      index: 5\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/Particles\n      index: 6\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-toolbar__top\n      displayed: 0\n      id: Brush Attributes\n      index: 2\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-toolbar__top\n      displayed: 1\n      id: unity-scene-view-camera-mode-toolbar\n      index: 2\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":24.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 24, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-toolbar__left\n      displayed: 0\n      id: Terrain Tools\n      index: 0\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 0\n      containerId: overlay-toolbar__left\n      displayed: 0\n      id: Brush Masks\n      index: 1\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--left\n      displayed: 0\n      id: Scene View/Lighting Visualization Colors\n      index: 0\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--left\n      displayed: 1\n      id: Overlays/OverlayMenu\n      index: 1\n      contents: '{\"m_Layout\":1,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":24.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":0.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 24, y: 0}\n      snapOffsetDelta: {x: 0, y: 0}\n      snapCorner: 0\n      layout: 1\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: SceneView/CamerasOverlay\n      index: 7\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/PBR Validation Settings\n      index: 8\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    - dockPosition: 1\n      containerId: overlay-container--right\n      displayed: 0\n      id: Scene View/TrailRenderer\n      index: 9\n      contents: '{\"m_Layout\":4,\"m_Collapsed\":false,\"m_Floating\":false,\"m_FloatingSnapOffset\":{\"x\":0.0,\"y\":0.0},\"m_SnapOffsetDelta\":{\"x\":24.0,\"y\":0.0},\"m_FloatingSnapCorner\":0,\"m_Size\":{\"x\":0.0,\"y\":0.0},\"m_SizeOverridden\":false}'\n      floating: 0\n      collapsed: 0\n      snapOffset: {x: 0, y: 0}\n      snapOffsetDelta: {x: 24, y: 0}\n      snapCorner: 0\n      layout: 4\n      size: {x: 0, y: 0}\n      sizeOverridden: 0\n    m_ContainerData:\n    - containerId: overlay-toolbar__top\n      scrollOffset: 0\n    - containerId: overlay-toolbar__left\n      scrollOffset: 0\n    - containerId: overlay-container--left\n      scrollOffset: 0\n    - containerId: overlay-container--right\n      scrollOffset: 0\n    - containerId: overlay-toolbar__right\n      scrollOffset: 0\n    - containerId: overlay-toolbar__bottom\n      scrollOffset: 0\n    - containerId: Floating\n      scrollOffset: 0\n    m_OverlaysVisible: 1\n  m_WindowGUID: 1acd90b02262845b2a933768b9dd2124\n  m_Gizmos: 1\n  m_OverrideSceneCullingMask: 6917529027641081856\n  m_SceneIsLit: 1\n  m_SceneLighting: 1\n  m_2DMode: 0\n  m_isRotationLocked: 0\n  m_PlayAudio: 0\n  m_AudioPlay: 0\n  m_DebugDrawModesUseInteractiveLightBakingData: 0\n  m_Position:\n    m_Target: {x: 0, y: 0, z: 0}\n    speed: 2\n    m_Value: {x: 0, y: 0, z: 0}\n  m_RenderMode: 0\n  m_CameraMode:\n    drawMode: 0\n    name: Shaded\n    section: Shading Mode\n  m_ValidateTrueMetals: 0\n  m_DoValidateTrueMetals: 0\n  m_SceneViewState:\n    m_AlwaysRefresh: 0\n    showFog: 1\n    showSkybox: 1\n    showFlares: 1\n    showImageEffects: 1\n    showParticleSystems: 1\n    showVisualEffectGraphs: 1\n    m_FxEnabled: 1\n  m_Grid:\n    xGrid:\n      m_Fade:\n        m_Target: 0\n        speed: 2\n        m_Value: 0\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 0, y: 0}\n    yGrid:\n      m_Fade:\n        m_Target: 1\n        speed: 2\n        m_Value: 1\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 1, y: 1}\n    zGrid:\n      m_Fade:\n        m_Target: 0\n        speed: 2\n        m_Value: 0\n      m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4}\n      m_Pivot: {x: 0, y: 0, z: 0}\n      m_Size: {x: 0, y: 0}\n    m_ShowGrid: 1\n    m_GridAxis: 1\n    m_gridOpacity: 0.5\n  m_Rotation:\n    m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}\n    speed: 2\n    m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}\n  m_Size:\n    m_Target: 10\n    speed: 2\n    m_Value: 10\n  m_Ortho:\n    m_Target: 0\n    speed: 2\n    m_Value: 0\n  m_CameraSettings:\n    m_Speed: 1\n    m_SpeedNormalized: 0.5\n    m_SpeedMin: 0.01\n    m_SpeedMax: 2\n    m_EasingEnabled: 1\n    m_EasingDuration: 0.4\n    m_AccelerationEnabled: 1\n    m_FieldOfViewHorizontalOrVertical: 60\n    m_NearClip: 0.03\n    m_FarClip: 10000\n    m_DynamicClip: 1\n    m_OcclusionCulling: 0\n  m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}\n  m_LastSceneViewOrtho: 0\n  m_Viewpoint:\n    m_SceneView: {fileID: 20}\n    m_CameraOverscanSettings:\n      m_Opacity: 50\n      m_Scale: 1\n  m_ReplacementShader: {fileID: 0}\n  m_ReplacementString: \n  m_SceneVisActive: 1\n  m_LastLockedObject: {fileID: 0}\n  m_LastDebugDrawMode: 35\n  m_ViewIsLockedToObject: 0\n--- !u!114 &21\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 200, y: 200}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Game\n    m_Image: {fileID: -6423792434712278376, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Game\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 507\n    y: 94\n    width: 1532\n    height: 790\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n  m_SerializedViewNames: []\n  m_SerializedViewValues: []\n  m_PlayModeViewName: GameView\n  m_ShowGizmos: 0\n  m_TargetDisplay: 0\n  m_ClearColor: {r: 0, g: 0, b: 0, a: 0}\n  m_TargetSize: {x: 1532, y: 769}\n  m_TextureFilterMode: 0\n  m_TextureHideFlags: 61\n  m_RenderIMGUI: 0\n  m_EnterPlayModeBehavior: 0\n  m_UseMipMap: 0\n  m_VSyncEnabled: 0\n  m_Gizmos: 0\n  m_Stats: 0\n  m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000\n  m_ZoomArea:\n    m_HRangeLocked: 0\n    m_VRangeLocked: 0\n    hZoomLockedByDefault: 0\n    vZoomLockedByDefault: 0\n    m_HBaseRangeMin: -766\n    m_HBaseRangeMax: 766\n    m_VBaseRangeMin: -384.5\n    m_VBaseRangeMax: 384.5\n    m_HAllowExceedBaseRangeMin: 1\n    m_HAllowExceedBaseRangeMax: 1\n    m_VAllowExceedBaseRangeMin: 1\n    m_VAllowExceedBaseRangeMax: 1\n    m_ScaleWithWindow: 0\n    m_HSlider: 0\n    m_VSlider: 0\n    m_IgnoreScrollWheelUntilClicked: 0\n    m_EnableMouseInput: 1\n    m_EnableSliderZoomHorizontal: 0\n    m_EnableSliderZoomVertical: 0\n    m_UniformScale: 1\n    m_UpDirection: 1\n    m_DrawArea:\n      serializedVersion: 2\n      x: 0\n      y: 21\n      width: 1532\n      height: 769\n    m_Scale: {x: 1, y: 1}\n    m_Translation: {x: 766, y: 384.5}\n    m_MarginLeft: 0\n    m_MarginRight: 0\n    m_MarginTop: 0\n    m_MarginBottom: 0\n    m_LastShownAreaInsideMargins:\n      serializedVersion: 2\n      x: -766\n      y: -384.5\n      width: 1532\n      height: 769\n    m_MinimalGUI: 1\n  m_defaultScale: 1\n  m_LastWindowPixelSize: {x: 1532, y: 790}\n  m_ClearInEditMode: 1\n  m_NoCameraWarning: 1\n  m_LowResolutionForAspectRatios: 00000000000000000000\n  m_XRRenderMode: 0\n  m_RenderTexture: {fileID: 0}\n  m_showToolbar: 1\n--- !u!114 &22\nMonoBehaviour:\n  m_ObjectHideFlags: 52\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 1\n  m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_MinSize: {x: 100, y: 100}\n  m_MaxSize: {x: 4000, y: 4000}\n  m_TitleContent:\n    m_Text: Console\n    m_Image: {fileID: -4327648978806127646, guid: 0000000000000000d000000000000000,\n      type: 0}\n    m_Tooltip: \n    m_TextWithWhitespace: \"Console\\u200B\"\n  m_Pos:\n    serializedVersion: 2\n    x: 1792\n    y: 655\n    width: 2038\n    height: 479\n  m_SerializedDataModeController:\n    m_DataMode: 0\n    m_PreferredDataMode: 0\n    m_SupportedDataModes: \n    isAutomatic: 1\n  m_ViewDataDictionary: {fileID: 0}\n  m_OverlayCanvas:\n    m_LastAppliedPresetName: Default\n    m_SaveData: []\n    m_ContainerData: []\n    m_OverlaysVisible: 1\n"
  },
  {
    "path": "UserSettings/Search.settings",
    "content": "{}"
  },
  {
    "path": "android-unity-wrapper/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor.xml\n/.idea/assetWizardSettings.xml\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\n\n# Signing keys\nsigning-key.gpg\ntemp_key.asc\n*.asc\n*.gpg\n\n# Gradle properties with secrets\ngradle.properties\n"
  },
  {
    "path": "android-unity-wrapper/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "android-unity-wrapper/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    namespace 'com.appsflyer.unitywrapper'\n    compileSdkVersion 34\n\n\n    defaultConfig {\n        applicationId \"com.appsflyer.unitywrapper\"\n        minSdkVersion 16\n        targetSdkVersion 34\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n\n    implementation 'androidx.appcompat:appcompat:1.1.0'\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.1'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'\n}\n"
  },
  {
    "path": "android-unity-wrapper/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "android-unity-wrapper/app/src/androidTest/java/com/appsflyer/unity/ExampleInstrumentedTest.java",
    "content": "package com.appsflyer.unity;\n\nimport android.content.Context;\n\nimport androidx.test.platform.app.InstrumentationRegistry;\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n\n        assertEquals(\"com.appsflyer.unitywrapper\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "android-unity-wrapper/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\" />\n</manifest>\n"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#6200EE</color>\n    <color name=\"colorPrimaryDark\">#3700B3</color>\n    <color name=\"colorAccent\">#03DAC5</color>\n</resources>\n"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">android-unity-wrapper</string>\n</resources>\n"
  },
  {
    "path": "android-unity-wrapper/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "android-unity-wrapper/app/src/test/java/com/appsflyer/unity/ExampleUnitTest.java",
    "content": "package com.appsflyer.unity;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "android-unity-wrapper/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    \n    ext {\n        agp_version = '8.5.0'\n        agp_version1 = '7.4.2'\n        agp_version2 = '7.1.0'\n        agp_version3 = '3.6.1'\n        agp_version4 = '8.10.1'\n    }\n    repositories {\n        google()\n        mavenCentral()\n        \n    }\n    dependencies {\n        classpath \"com.android.tools.build:gradle:$agp_version4\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nplugins {\n    id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'\n}\n\ndef getSonatypeRepositoryToken() { return hasProperty('ossrhToken') ? ossrhToken : \"\" }\n\ndef getSonatypeRepositoryTokenPassword() { return hasProperty('ossrhTokenPassword') ? ossrhTokenPassword : \"\" }\n\nnexusPublishing {\n    packageGroup = GROUP // optional if packageGroup == project.getGroup()\n    repositories {\n        sonatype {\n            nexusUrl = uri(\"https://ossrh-staging-api.central.sonatype.com/service/local/\")\n            snapshotRepositoryUrl = uri(\"https://central.sonatype.com/repository/maven-snapshots/\")\n            username = getSonatypeRepositoryToken()\n            password = getSonatypeRepositoryTokenPassword()\n        }\n    }\n    transitionCheckOptions {\n        maxRetries.set(120)\n        delayBetween.set(java.time.Duration.ofMillis(30000))\n    }\n}\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n        \n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "android-unity-wrapper/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Jan 21 12:53:02 IST 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.11.1-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "android-unity-wrapper/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "android-unity-wrapper/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "android-unity-wrapper/settings.gradle",
    "content": "rootProject.name='android-unity-wrapper'\ninclude ':app'\ninclude ':unitywrapper'\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    namespace \"com.appsflyer.unitywrapper\"\n    compileSdkVersion 34\n\n    defaultConfig {\n        minSdkVersion 16\n        targetSdkVersion 34\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles 'consumer-rules.pro'\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n\n}\n\nrepositories {\n    mavenCentral()\n}\n\n\ndependencies {\n    compileOnly fileTree(dir: 'libs', include: ['*.jar'])\n    compileOnly 'androidx.appcompat:appcompat:1.1.0'\n    compileOnly 'com.appsflyer:af-android-sdk:6.17.6'\n    compileOnly 'com.appsflyer:purchase-connector:2.2.0'\n    compileOnly 'com.android.billingclient:billing:8.0.0'\n}\n\napply from: file('publish.gradle')\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "android-unity-wrapper/unitywrapper/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/publish.gradle",
    "content": "apply plugin: 'maven-publish'\napply plugin: 'signing'\n\ndef isReleaseBuild() {\n    return !VERSION_NAME.contains(\"-SNAPSHOT\")\n}\n\n\n\nandroid {\n    publishing {\n        singleVariant(\"release\") {\n            // if you don't want sources/javadoc, remove these lines\n            withJavadocJar()\n        }\n    }\n}\n\nafterEvaluate {\n    publishing {\n        publications {\n            release(MavenPublication) {\n                // The coordinates of the library\n                groupId = GROUP\n                artifactId = POM_ARTIFACT_ID\n                version = VERSION_NAME\n\n                // Artifacts to publish\n                artifact(\"$buildDir/outputs/aar/${project.name}-release.aar\")\n\n                // Configure POM metadata\n                pom {\n                    name.set(POM_NAME)\n                    description.set(POM_DESCRIPTION)\n                    url.set(POM_URL)\n\n                    licenses {\n                        license {\n                            name.set(POM_LICENCE_NAME)\n                            url.set(POM_LICENCE_URL)\n                            distribution.set(POM_LICENCE_DIST)\n                        }\n                    }\n\n                    developers {\n                        developer {\n                            id.set(POM_DEVELOPER_ID)\n                            name.set(POM_DEVELOPER_NAME)\n                        }\n                    }\n\n                    scm {\n                        connection.set(POM_SCM_CONNECTION)\n                        developerConnection.set(POM_SCM_DEV_CONNECTION)\n                        url.set(POM_SCM_URL)\n                    }\n                }\n\n                // Add dependencies to the POM\n                pom.withXml {\n                    def dependenciesNode = asNode().appendNode('dependencies')\n                    configurations.implementation.allDependencies.each { dependency ->\n                        def dependencyNode = dependenciesNode.appendNode('dependency')\n                        dependencyNode.appendNode('groupId', dependency.group ?: '')\n                        dependencyNode.appendNode('artifactId', dependency.name)\n                        dependencyNode.appendNode('version', dependency.version ?: '')\n                    }\n                }\n            }\n        }\n\n\n    }\n\n\n    def decodedKey = project.findProperty(\"signing.secretKey\")?.replace('\\\\n', '\\n')\n\n    signing {\n        // 🧪 STEP 2: Use the decoded key INSIDE the signing block\n        if (project.hasProperty(\"signing.keyId\") &&\n                decodedKey &&\n                project.hasProperty(\"signing.password\")) {\n\n            useInMemoryPgpKeys(\n                    project.findProperty(\"signing.keyId\")?.toString(),\n                    decodedKey,\n                    project.findProperty(\"signing.password\")?.toString()\n            )\n        }\n\n        sign publishing.publications.release\n    }\n//    task androidJavadocs(type: Javadoc) {\n//        classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n//        if (JavaVersion.current().isJava8Compatible()) {\n//                tasks.withType(Javadoc) { options.addStringOption('Xdoclint:none', '-quiet') }\n//            }\n//        }\n//    }\n//    task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {\n//        archiveClassifier = 'javadoc'\n//        from androidJavadocs.destinationDir\n//    }\n//    task androidSourcesJar(type: Jar) {\n//        classifier = 'sources'\n//        from android.sourceSets.main.java.sourceFiles\n//    }\n//    artifacts { archives androidJavadocsJar }\n}"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"/>\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/src/main/java/com/appsflyer/unity/AppsFlyerAndroidWrapper.java",
    "content": "package com.appsflyer.unity;\n\nimport android.annotation.SuppressLint;\nimport android.os.Build;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.RequiresApi;\n\nimport com.appsflyer.api.InAppPurchaseEvent;\nimport com.appsflyer.api.PurchaseClient;\nimport com.appsflyer.api.Store;\nimport com.appsflyer.api.SubscriptionPurchaseEvent;\nimport com.appsflyer.internal.models.InAppPurchaseValidationResult;\nimport com.appsflyer.internal.models.ProductPurchase;\nimport com.appsflyer.internal.models.SubscriptionPurchase;\nimport com.appsflyer.internal.models.SubscriptionValidationResult;\nimport com.appsflyer.internal.models.ValidationFailureData;\n\nimport com.appsflyer.AFAdRevenueData;\nimport com.appsflyer.MediationNetwork;\nimport com.appsflyer.AFLogger;\nimport com.appsflyer.AFPurchaseDetails;\nimport com.appsflyer.AFPurchaseType;\nimport com.appsflyer.AppsFlyerConsent;\nimport com.appsflyer.AppsFlyerConversionListener;\nimport com.appsflyer.AppsFlyerInAppPurchaseValidationCallback;\nimport com.appsflyer.AppsFlyerInAppPurchaseValidatorListener;\nimport com.appsflyer.AppsFlyerLib;\nimport com.appsflyer.AppsFlyerProperties;\nimport com.appsflyer.attribution.AppsFlyerRequestListener;\nimport com.appsflyer.deeplink.DeepLinkListener;\nimport com.appsflyer.deeplink.DeepLinkResult;\nimport com.appsflyer.internal.platform_extension.Plugin;\nimport com.appsflyer.internal.platform_extension.PluginInfo;\nimport com.appsflyer.share.CrossPromotionHelper;\nimport com.appsflyer.share.LinkGenerator;\nimport com.appsflyer.share.ShareInviteHelper;\nimport com.unity3d.player.UnityPlayer;\n\nimport org.json.JSONObject;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n\npublic class AppsFlyerAndroidWrapper {\n\n    private static final String VALIDATE_CALLBACK = \"didFinishValidateReceipt\";\n    private static final String VALIDATE_ERROR_CALLBACK = \"didFinishValidateReceiptWithError\";\n    private static final String VALIDATE_AND_LOG_V2_CALLBACK = \"onValidateAndLogComplete\";\n    private static final String VALIDATE_AND_LOG_V2__ERROR_CALLBACK = \"onValidateAndLogFailure\";\n    private static final String GCD_CALLBACK = \"onConversionDataSuccess\";\n    private static final String GCD_ERROR_CALLBACK = \"onConversionDataFail\";\n    private static final String OAOA_CALLBACK = \"onAppOpenAttribution\";\n    private static final String OAOA_ERROR_CALLBACK = \"onAppOpenAttributionFailure\";\n    private static final String GENERATE_LINK_CALLBACK = \"onInviteLinkGenerated\";\n    private static final String GENERATE_LINK_ERROR_CALLBACK = \"onInviteLinkGeneratedFailure\";\n    private static final String ON_DEEPLINKING = \"onDeepLinking\";\n    private static final String START_REQUEST_CALLBACK = \"requestResponseReceived\";\n    private static final String IN_APP_RESPONSE_CALLBACK = \"inAppResponseReceived\";\n    private static final String VALIDATION_CALLBACK = \"didReceivePurchaseRevenueValidationInfo\";\n    private static final String ERROR_CALLBACK = \"didReceivePurchaseRevenueError\";\n    private static final String PLUGIN_VERSION = \"6.17.91\";\n\n    private static final long DDL_TIMEOUT_DEFAULT = 3000;\n    private static AppsFlyerConversionListener conversionListener;\n    private static String devkey = \"\";\n    private static long ddlTimeout = DDL_TIMEOUT_DEFAULT;\n\n    private static PurchaseClient purchaseClientInstance;\n    private static PurchaseClient.Builder builder;\n\n    private static String unityObjectName;\n\n    public static void initSDK(String devKey, String objectName) {\n        if (conversionListener == null && objectName != null){\n            conversionListener = getConversionListener(objectName);\n        }\n\n        devkey = devKey;\n        setPluginInfo();\n        AppsFlyerLib.getInstance().init(devKey, conversionListener, UnityPlayer.currentActivity);\n    }\n\n    public static void startTracking(final boolean shouldCallback, final String objectName) {\n        AppsFlyerLib.getInstance().start(UnityPlayer.currentActivity, devkey, new AppsFlyerRequestListener() {\n            @Override\n            public void onSuccess() {\n                if(shouldCallback && objectName != null){\n                    Map<String,Object> map = new HashMap<String,Object>();\n                    map.put(\"statusCode\", 200);\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, START_REQUEST_CALLBACK, jsonObject.toString());\n                }\n            }\n\n            @Override\n            public void onError(int i, @NonNull String s) {\n                if(shouldCallback && objectName != null){\n                    Map<String,Object> map = new HashMap<String,Object>();\n                    map.put(\"statusCode\", i);\n                    map.put(\"errorDescription\", s);\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, START_REQUEST_CALLBACK, jsonObject.toString());\n                }\n            }\n        });\n    }\n\n    public static void startTracking() {\n        startTracking(false, null);\n    }\n\n    public static void stopTracking(boolean isTrackingStopped) {\n        AppsFlyerLib.getInstance().stop(isTrackingStopped, UnityPlayer.currentActivity);\n    }\n\n    public static String getSdkVersion() {\n        return AppsFlyerLib.getInstance().getSdkVersion();\n    }\n\n    public static void updateServerUninstallToken(String token) {\n        AppsFlyerLib.getInstance().updateServerUninstallToken(UnityPlayer.currentActivity, token);\n    }\n\n    public static void setIsDebug(boolean shouldEnable) {\n        AppsFlyerLib.getInstance().setDebugLog(shouldEnable);\n    }\n\n    public static void setImeiData(String aImei) {\n        AppsFlyerLib.getInstance().setImeiData(aImei);\n\n    }\n\n    public static void setAndroidIdData(String aAndroidId) {\n        AppsFlyerLib.getInstance().setAndroidIdData(aAndroidId);\n    }\n\n    public static void setCustomerUserId(String id) {\n        AppsFlyerLib.getInstance().setCustomerUserId(id);\n    }\n\n    public static void waitForCustomerUserId(boolean wait) {\n        AppsFlyerLib.getInstance().waitForCustomerUserId(true);\n    }\n\n    public static void setCustomerIdAndTrack(String id) {\n        AppsFlyerLib.getInstance().setCustomerIdAndLogSession(id, UnityPlayer.currentActivity);\n    }\n\n    public static void enableTCFDataCollection(boolean shouldCollectTcfData) {\n        AppsFlyerLib.getInstance().enableTCFDataCollection(shouldCollectTcfData);\n    }\n\n    public static void setConsentData(String isUserSubjectToGDPR, String hasConsentForDataUsage, String hasConsentForAdsPersonalization, String hasConsentForAdStorage) {\n\n        Boolean gdprApplies = parseNullableBoolean(isUserSubjectToGDPR);\n        Boolean dataUsage = parseNullableBoolean(hasConsentForDataUsage);\n        Boolean adsPersonalization = parseNullableBoolean(hasConsentForAdsPersonalization);\n        Boolean adStorage = parseNullableBoolean(hasConsentForAdStorage);\n\n        AppsFlyerLib.getInstance().setConsentData(new AppsFlyerConsent(gdprApplies, dataUsage, adsPersonalization, adStorage));\n    }\n\n    public static void logAdRevenue(String monetizationNetwork, MediationNetwork mediationNetwork, String currencyIso4217Code, double revenue, HashMap<String, Object> additionalParameters) {\n        AFAdRevenueData adRevenueData = new AFAdRevenueData(monetizationNetwork, mediationNetwork, currencyIso4217Code, revenue);\n        AppsFlyerLib.getInstance().logAdRevenue(adRevenueData, additionalParameters);\n    }\n\n    public static String getOutOfStore() {\n        return AppsFlyerLib.getInstance().getOutOfStore(UnityPlayer.currentActivity);\n    }\n\n    public static void setOutOfStore(String sourceName) {\n        AppsFlyerLib.getInstance().setOutOfStore(sourceName);\n    }\n\n    public static void setAppInviteOneLinkID(String oneLinkId) {\n        AppsFlyerLib.getInstance().setAppInviteOneLink(oneLinkId);\n    }\n\n    public static void setAdditionalData(HashMap<String, Object> customData) {\n        AppsFlyerLib.getInstance().setAdditionalData(customData);\n    }\n\n    public static void setUserEmails(String... emails) {\n        AppsFlyerLib.getInstance().setUserEmails(emails);\n    }\n\n    public static void setUserEmails(AppsFlyerProperties.EmailsCryptType cryptMethod, String... emails) {\n        AppsFlyerLib.getInstance().setUserEmails(cryptMethod, emails);\n    }\n\n    public static void setCollectAndroidID(boolean isCollect) {\n        AppsFlyerLib.getInstance().setCollectAndroidID(isCollect);\n    }\n\n    public static void setCollectIMEI(boolean isCollect) {\n        AppsFlyerLib.getInstance().setCollectIMEI(isCollect);\n    }\n\n    public static void setResolveDeepLinkURLs(String... urls) {\n        AppsFlyerLib.getInstance().setResolveDeepLinkURLs(urls);\n    }\n\n    public static void setOneLinkCustomDomain(String... domains) {\n        AppsFlyerLib.getInstance().setOneLinkCustomDomain(domains);\n    }\n\n    public static void setIsUpdate(boolean isUpdate) {\n        AppsFlyerLib.getInstance().setIsUpdate(isUpdate);\n    }\n\n    public static void setCurrencyCode(String currencyCode) {\n        AppsFlyerLib.getInstance().setCurrencyCode(currencyCode);\n    }\n\n    public static void trackLocation(double latitude, double longitude) {\n        AppsFlyerLib.getInstance().logLocation(UnityPlayer.currentActivity, latitude, longitude);\n    }\n\n    public static void trackEvent(String eventName, HashMap<String, Object> eventValues, final boolean shouldCallback, final String objectName) {\n        AppsFlyerLib.getInstance().logEvent(UnityPlayer.currentActivity, eventName, eventValues, new AppsFlyerRequestListener() {\n            @Override\n            public void onSuccess() {\n                if(shouldCallback && objectName != null){\n                    Map<String,Object> map = new HashMap<String,Object>();\n                    map.put(\"statusCode\", 200);\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, IN_APP_RESPONSE_CALLBACK, jsonObject.toString());\n                }\n            }\n\n            @Override\n            public void onError(int i, @NonNull String s) {\n                if(shouldCallback && objectName != null){\n                    Map<String,Object> map = new HashMap<String,Object>();\n                    map.put(\"statusCode\", i);\n                    map.put(\"errorDescription\", s);\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, IN_APP_RESPONSE_CALLBACK, jsonObject.toString());\n                }\n            }\n        });\n    }\n\n    public static void trackEvent(String eventName, HashMap<String, Object> eventValues) {\n        trackEvent(eventName, eventValues, false, null);\n    }\n\n    public static void setDeviceTrackingDisabled(boolean isDisabled) {\n        AppsFlyerLib.getInstance().anonymizeUser(isDisabled);\n    }\n\n    public static void enableFacebookDeferredApplinks(boolean isEnabled) {\n        AppsFlyerLib.getInstance().enableFacebookDeferredApplinks(isEnabled);\n    }\n\n    public static void setConsumeAFDeepLinks(boolean doConsume) {\n        //AppsFlyerLib.getInstance().setConsumeAFDeepLinks(doConsume);\n    }\n\n    public static void setPreinstallAttribution(String mediaSource, String campaign, String siteId) {\n        AppsFlyerLib.getInstance().setPreinstallAttribution(mediaSource, campaign, siteId);\n    }\n\n    public static boolean isPreInstalledApp() {\n        return AppsFlyerLib.getInstance().isPreInstalledApp(UnityPlayer.currentActivity);\n    }\n\n    public static String getAttributionId() {\n        return AppsFlyerLib.getInstance().getAttributionId(UnityPlayer.currentActivity);\n    }\n\n    public static String getAppsFlyerId() {\n        return AppsFlyerLib.getInstance().getAppsFlyerUID(UnityPlayer.currentActivity);\n    }\n\n    public static void validateAndTrackInAppPurchase(String publicKey, String signature, String purchaseData, String price, String currency, HashMap<String, String> additionalParameters, String objectName) {\n        AppsFlyerLib.getInstance().validateAndLogInAppPurchase(UnityPlayer.currentActivity, publicKey, signature, purchaseData, price, currency, additionalParameters);\n        if (objectName != null){\n            initInAppPurchaseValidatorListener(objectName);\n        }\n    }\n\n    public static void validateAndTrackInAppPurchaseV2(int purchaseType, String purchaseToken, String productId, HashMap<String, String> purchaseAdditionalDetails, final String objectName) {\n        AFPurchaseType type = purchaseType == 0 ? AFPurchaseType.SUBSCRIPTION : AFPurchaseType.ONE_TIME_PURCHASE;\n        AFPurchaseDetails details = new AFPurchaseDetails(type, purchaseToken, productId);\n\n        if (objectName != null){\n            AppsFlyerInAppPurchaseValidationCallback listener = initInAppPurchaseValidatorV2Listener(objectName);\n            AppsFlyerLib.getInstance().validateAndLogInAppPurchase(details, purchaseAdditionalDetails, listener);\n        }\n    }\n\n    public static boolean isTrackingStopped() {\n        return AppsFlyerLib.getInstance().isStopped();\n    }\n\n    public static void setMinTimeBetweenSessions(int seconds) {\n        AppsFlyerLib.getInstance().setMinTimeBetweenSessions(seconds);\n    }\n\n    public static void setLogLevel(AFLogger.LogLevel logLevel) {\n        AppsFlyerLib.getInstance().setLogLevel(logLevel);\n    }\n\n    public static void setHost(String hostPrefixName, String hostName) {\n        AppsFlyerLib.getInstance().setHost(hostPrefixName, hostName);\n    }\n\n    public static String getHostName() {\n        return AppsFlyerLib.getInstance().getHostName();\n    }\n\n    public static String getHostPrefix() {\n        return AppsFlyerLib.getInstance().getHostPrefix();\n    }\n\n    public static void setCollectOaid(boolean isCollect) {\n        AppsFlyerLib.getInstance().setCollectOaid(isCollect);\n    }\n\n    public static void setSharingFilterForAllPartners() {\n        AppsFlyerLib.getInstance().setSharingFilterForAllPartners();\n    }\n\n    public static void setSharingFilter(String ... partners) {\n        AppsFlyerLib.getInstance().setSharingFilter(partners);\n    }\n\n    public static void getConversionData(final String objectName){\n        if (conversionListener == null){\n            conversionListener = getConversionListener(objectName);\n        }\n\n        AppsFlyerLib.getInstance().registerConversionListener(UnityPlayer.currentActivity, conversionListener);\n    }\n\n    private static AppsFlyerConversionListener getConversionListener(final String objectName){\n\n        return new AppsFlyerConversionListener() {\n            @Override\n            public void onConversionDataSuccess(Map<String, Object> map) {\n                if(objectName != null){\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, GCD_CALLBACK, jsonObject.toString());\n                }\n            }\n\n            @Override\n            public void onConversionDataFail(String s) {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, GCD_ERROR_CALLBACK, s);\n                }\n            }\n\n            @Override\n            public void onAppOpenAttribution(Map<String, String> map) {\n                if(objectName != null){\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, OAOA_CALLBACK, jsonObject.toString());\n                }\n            }\n\n            @Override\n            public void onAttributionFailure(String s) {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, OAOA_ERROR_CALLBACK, s);\n                }\n            }\n        };\n    }\n\n    private static Boolean parseNullableBoolean(String value) {\n        if (value == null) return null;\n        if (value.equalsIgnoreCase(\"true\")) return true;\n        if (value.equalsIgnoreCase(\"false\")) return false;\n        return null;\n    }\n\n    public static void initInAppPurchaseValidatorListener(final String objectName) {\n        AppsFlyerLib.getInstance().registerValidatorListener(UnityPlayer.currentActivity, new AppsFlyerInAppPurchaseValidatorListener() {\n            @Override\n            public void onValidateInApp() {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, VALIDATE_CALLBACK, \"Validate success\");\n                }\n            }\n\n            @Override\n            public void onValidateInAppFailure(String error) {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, VALIDATE_ERROR_CALLBACK, error);\n                }\n            }\n        });\n    }\n\n    public static AppsFlyerInAppPurchaseValidationCallback initInAppPurchaseValidatorV2Listener(final String objectName) {\n        return new AppsFlyerInAppPurchaseValidationCallback() {\n            @Override\n            public void onInAppPurchaseValidationFinished(@NonNull Map<String, ?> map) {\n                if (objectName != null) {\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, VALIDATE_AND_LOG_V2_CALLBACK, jsonObject.toString());\n                }\n            }\n\n            @Override\n            public void onInAppPurchaseValidationError(@NonNull Map<String, ?> map) {\n                if (objectName != null) {\n                    JSONObject jsonObject = new JSONObject(map);\n                    UnityPlayer.UnitySendMessage(objectName, VALIDATE_AND_LOG_V2__ERROR_CALLBACK, jsonObject.toString());\n                }\n            }\n        };\n    }\n\n    public static void handlePushNotifications(){\n        AppsFlyerLib.getInstance().sendPushNotificationData(UnityPlayer.currentActivity);\n    }\n\n    public static void setPhoneNumber(String phoneNumber){\n        AppsFlyerLib.getInstance().setPhoneNumber(phoneNumber);\n    }\n\n    public static void attributeAndOpenStore(String promoted_app_id, String campaign, Map<String, String> userParams) {\n        CrossPromotionHelper.logAndOpenStore(UnityPlayer.currentActivity, promoted_app_id, campaign, userParams);\n    }\n\n    public static void recordCrossPromoteImpression(String appID, String campaign, Map<String,String> params){\n        CrossPromotionHelper.logCrossPromoteImpression(UnityPlayer.currentActivity, appID, campaign, params);\n    }\n\n    public static void createOneLinkInviteListener(Map<String,String> params, final String objectName){\n\n        LinkGenerator linkGenerator = ShareInviteHelper.generateInviteUrl(UnityPlayer.currentActivity);\n\n        linkGenerator.setChannel(params.get(\"channel\"));\n        linkGenerator.setCampaign(params.get(\"campaign\"));\n        linkGenerator.setReferrerName(params.get(\"referrerName\"));\n        linkGenerator.setReferrerImageURL(params.get(\"referrerImageUrl\"));\n        linkGenerator.setReferrerCustomerId(params.get(\"customerID\"));\n        linkGenerator.setBaseDeeplink(params.get(\"baseDeepLink\"));\n        linkGenerator.setBrandDomain(params.get(\"brandDomain\"));\n\n        params.remove(\"channel\");\n        params.remove(\"campaign\");\n        params.remove(\"referrerName\");\n        params.remove(\"referrerImageUrl\");\n        params.remove(\"customerID\");\n        params.remove(\"baseDeepLink\");\n        params.remove(\"brandDomain\");\n\n        linkGenerator.addParameters(params);\n\n        linkGenerator.generateLink(UnityPlayer.currentActivity, new LinkGenerator.ResponseListener() {\n            @Override\n            public void onResponse(String link) {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, GENERATE_LINK_CALLBACK, link);\n                }\n            }\n\n            @Override\n            public void onResponseError(String error) {\n                if(objectName != null){\n                    UnityPlayer.UnitySendMessage(objectName, GENERATE_LINK_ERROR_CALLBACK, error);\n                }\n            }\n        });\n\n    }\n\n    public static void subscribeForDeepLink(final String objectName){\n        if (ddlTimeout != DDL_TIMEOUT_DEFAULT) {\n            AppsFlyerLib.getInstance().subscribeForDeepLink(new DeepLinkListener() {\n                @Override\n                public void onDeepLinking(@NonNull DeepLinkResult deepLinkResult) {\n                    if(objectName != null){\n                        UnityPlayer.UnitySendMessage(objectName, ON_DEEPLINKING, deepLinkResult.toString());\n                    }\n                }\n            }, ddlTimeout);\n        } else\n        {\n            AppsFlyerLib.getInstance().subscribeForDeepLink(new DeepLinkListener() {\n                @Override\n                public void onDeepLinking(@NonNull DeepLinkResult deepLinkResult) {\n                    if(objectName != null){\n                        UnityPlayer.UnitySendMessage(objectName, ON_DEEPLINKING, deepLinkResult.toString());\n                    }\n                }\n            });\n        }\n    }\n\n    public static void addPushNotificationDeepLinkPath(String ... path){\n        AppsFlyerLib.getInstance().addPushNotificationDeepLinkPath(path);\n    }\n\n    public static void setDisableAdvertisingIdentifiers(boolean disable){\n        AppsFlyerLib.getInstance().setDisableAdvertisingIdentifiers(disable);\n    }\n\n    public static void setSharingFilterForPartners(java.lang.String... partners){\n        AppsFlyerLib.getInstance().setSharingFilterForPartners(partners);\n    }\n\n    public static void setDisableNetworkData(boolean disable){\n        AppsFlyerLib.getInstance().setDisableNetworkData(disable);\n    }\n\n    public static void setPluginInfo() {\n        PluginInfo pluginInfo = new PluginInfo(Plugin.UNITY, PLUGIN_VERSION);\n        AppsFlyerLib.getInstance().setPluginInfo(pluginInfo);\n    }\n\n    public static void setDeepLinkTimeout(long deepLinkTimeout) {\n        ddlTimeout = deepLinkTimeout;\n    }\n\n\n    //Purchase Connector\n    public static void initPurchaseConnector(String objectName, int store) {\n        unityObjectName = objectName;\n        Store s = mappingEnum(store);\n        if (s != null) {\n            builder = new PurchaseClient.Builder(UnityPlayer.currentActivity, s);\n            builder = PurchaseRevenueBridge.configurePurchaseClient(builder);\n        } else {\n            Log.w(\"AppsFlyer_Connector\", \"[PurchaseConnector]: Please choose a valid store.\");\n        }\n    }\n\n    public static void build() {\n        if (builder != null) {\n            purchaseClientInstance = builder.build();\n        } else {\n            Log.w(\"AppsFlyer_Connector\", \"[PurchaseConnector]: Initialization is required prior to building.\");\n        }\n    }\n\n\n    public static void setIsSandbox(boolean isSandbox) {\n        if (builder != null) {\n            builder.setSandbox(isSandbox);\n        }\n    }\n\n    public static void setAutoLogSubscriptions(boolean logSubscriptions) {\n        if (builder != null) {\n            builder.logSubscriptions(logSubscriptions);\n        }\n    }\n\n    public static void setAutoLogInApps(boolean autoLogInApps) {\n        if (builder != null) {\n            builder.autoLogInApps(autoLogInApps);\n        }\n    }\n\n    public static void setPurchaseRevenueValidationListeners(boolean enableCallbacks) {\n        if (builder != null && enableCallbacks) {\n            builder.setSubscriptionValidationResultListener(new PurchaseClient.SubscriptionPurchaseValidationResultListener() {\n                @RequiresApi(api = Build.VERSION_CODES.N)\n                @Override\n                public void onResponse(@Nullable Map<String, ? extends SubscriptionValidationResult> result) {\n                    if (unityObjectName != null) {\n                        if (result == null) {\n                            return;\n                        }\n                        result.forEach((k, v) -> {\n                            Map<String, Object> map = new HashMap<>();\n                            Map<String, Object> mapSubscription = new HashMap<>();\n\n                            map.put(\"productId\", k);\n                            map.put(\"success\", v.getSuccess() ? \"true\" : \"false\");\n                            if (v.getSuccess()) {\n                                SubscriptionPurchase subscriptionPurchase = v.getSubscriptionPurchase();\n                                Map<String, Object> mapCancelSurveyResult = new HashMap<>();\n                                if (subscriptionPurchase.getCanceledStateContext() != null) {\n                                    Map<String, Object> mapCanceledStateContext = new HashMap<>();\n                                    Map<String, Object> mapUserInitiatedCancellation = new HashMap<>();\n                                    if (subscriptionPurchase.getCanceledStateContext().\n                                            getUserInitiatedCancellation() != null) {\n                                        if (subscriptionPurchase.getCanceledStateContext().\n                                                getUserInitiatedCancellation().\n                                                getCancelSurveyResult() != null) {\n                                            mapCancelSurveyResult.put(\"reason\",\n                                                    subscriptionPurchase.getCanceledStateContext().\n                                                            getUserInitiatedCancellation().\n                                                            getCancelSurveyResult().getReason());\n                                            mapCancelSurveyResult.put(\"reasonUserInput\",\n                                                    subscriptionPurchase.getCanceledStateContext().\n                                                            getUserInitiatedCancellation().\n                                                            getCancelSurveyResult().getReasonUserInput());\n                                            mapUserInitiatedCancellation.put(\"cancelSurveyResult\",\n                                                    mapCancelSurveyResult);\n                                        }\n                                        mapUserInitiatedCancellation.put(\"cancelTime\",\n                                                subscriptionPurchase.getCanceledStateContext().\n                                                        getUserInitiatedCancellation().getCancelTime());\n                                    }\n                                    mapCanceledStateContext.put(\"developerInitiatedCancellation\",\n                                            null);\n                                    mapCanceledStateContext.put(\"replacementCancellation\",\n                                            null);\n                                    mapCanceledStateContext.put(\"systemInitiatedCancellation\",\n                                            null);\n                                    mapCanceledStateContext.put(\"userInitiatedCancellation\",\n                                            mapUserInitiatedCancellation);\n                                }\n                                if (subscriptionPurchase.getExternalAccountIdentifiers() != null) {\n                                    Map<String, Object> mapExternalAccountIdentifiers = new HashMap<>();\n                                    mapExternalAccountIdentifiers.put(\"externalAccountId\",\n                                            subscriptionPurchase.getExternalAccountIdentifiers().\n                                                    getExternalAccountId());\n                                    mapExternalAccountIdentifiers.put(\"obfuscatedExternalAccountId\",\n                                            subscriptionPurchase.getExternalAccountIdentifiers().\n                                                    getObfuscatedExternalAccountId());\n                                    mapExternalAccountIdentifiers.put(\"obfuscatedExternalProfileId\",\n                                            subscriptionPurchase.getExternalAccountIdentifiers().\n                                                    getObfuscatedExternalProfileId());\n                                    mapSubscription.put(\"externalAccountIdentifiers\",\n                                            mapExternalAccountIdentifiers);\n                                }\n                                if (subscriptionPurchase.getPausedStateContext() != null) {\n                                    Map<String, Object> mapPausedStateContext = new HashMap<>();\n                                    mapPausedStateContext.put(\"autoResumeTime\",\n                                            subscriptionPurchase.getPausedStateContext().\n                                                    getAutoResumeTime());\n                                    mapSubscription.put(\"pausedStateContext\", mapPausedStateContext);\n\n\n                                }\n                                if (subscriptionPurchase.getSubscribeWithGoogleInfo() != null) {\n                                    Map<String, Object> mapSubscribeWithGoogleInfo = new HashMap<>();\n                                    mapSubscribeWithGoogleInfo.put(\"emailAddress\",\n                                            subscriptionPurchase.getSubscribeWithGoogleInfo().getEmailAddress());\n                                    mapSubscribeWithGoogleInfo.put(\"familyName\",\n                                            subscriptionPurchase.getSubscribeWithGoogleInfo().getFamilyName());\n                                    mapSubscribeWithGoogleInfo.put(\"givenName\",\n                                            subscriptionPurchase.getSubscribeWithGoogleInfo().getGivenName());\n                                    mapSubscribeWithGoogleInfo.put(\"profileId\",\n                                            subscriptionPurchase.getSubscribeWithGoogleInfo().getProfileId());\n                                    mapSubscribeWithGoogleInfo.put(\"profileName\",\n                                            subscriptionPurchase.getSubscribeWithGoogleInfo().getProfileName());\n                                    mapSubscription.put(\"subscribeWithGoogleInfo\",\n                                            mapSubscribeWithGoogleInfo);\n                                }\n                                int sizeItems = subscriptionPurchase.getLineItems().size();\n                                Map<String, Object>[] lineItems = new Map[sizeItems];\n                                for (int i = 0; i < sizeItems; i++) {\n                                    Map<String, Object> mapSubscriptionPurchaseLineItem = new HashMap<>();\n                                    mapSubscriptionPurchaseLineItem.put(\"expiryTime\",\n                                            subscriptionPurchase.getLineItems().get(i).getExpiryTime());\n                                    mapSubscriptionPurchaseLineItem.put(\"productId\",\n                                            subscriptionPurchase.getLineItems().get(i).getProductId());\n                                    if (subscriptionPurchase.getLineItems().get(i).getAutoRenewingPlan()\n                                            != null) {\n                                        Map<String, Object> mapAutoRenewingPlan = new HashMap<>();\n                                        if (subscriptionPurchase.getLineItems().get(i).\n                                                getAutoRenewingPlan().getAutoRenewEnabled() != null) {\n                                            mapAutoRenewingPlan.put(\"autoRenewEnabled\",\n                                                    subscriptionPurchase.getLineItems().get(i).getAutoRenewingPlan().\n                                                            getAutoRenewEnabled() ? \"true\" : \"false\");\n                                        }\n                                        if (subscriptionPurchase.getLineItems().get(i).getAutoRenewingPlan().\n                                                getPriceChangeDetails() != null) {\n                                            Map<String, Object> mapPriceChangeDetails = new HashMap<>();\n                                            mapPriceChangeDetails.put(\"expectedNewPriceChargeTime\",\n                                                    subscriptionPurchase.getLineItems().get(i).\n                                                            getAutoRenewingPlan().getPriceChangeDetails().\n                                                            getExpectedNewPriceChargeTime());\n                                            mapPriceChangeDetails.put(\"priceChangeMode\",\n                                                    subscriptionPurchase.getLineItems().get(i).\n                                                            getAutoRenewingPlan().\n                                                            getPriceChangeDetails().getPriceChangeMode());\n                                            mapPriceChangeDetails.put(\"priceChangeState\",\n                                                    subscriptionPurchase.getLineItems().get(i).\n                                                            getAutoRenewingPlan().\n                                                            getPriceChangeDetails().getPriceChangeState());\n                                            mapAutoRenewingPlan.put(\"priceChangeDetails\", mapPriceChangeDetails);\n                                            if (subscriptionPurchase.getLineItems().get(i).\n                                                    getAutoRenewingPlan().getPriceChangeDetails().\n                                                    getNewPrice() != null) {\n                                                Map<String, Object> mapMoney = new HashMap<>();\n                                                mapMoney.put(\"currencyCode\",\n                                                        subscriptionPurchase.getLineItems().get(i).\n                                                                getAutoRenewingPlan().\n                                                                getPriceChangeDetails().getNewPrice().\n                                                                getCurrencyCode());\n                                                mapMoney.put(\"nanos\",\n                                                        subscriptionPurchase.getLineItems().get(i).\n                                                                getAutoRenewingPlan().\n                                                                getPriceChangeDetails().getNewPrice().getNanos());\n                                                mapMoney.put(\"units\",\n                                                        subscriptionPurchase.getLineItems().get(i).\n                                                                getAutoRenewingPlan().\n                                                                getPriceChangeDetails().getNewPrice().getUnits());\n                                                mapPriceChangeDetails.put(\"newPrice\", mapMoney);\n                                            }\n                                        }\n                                        mapSubscriptionPurchaseLineItem.put(\"autoRenewingPlan\", mapAutoRenewingPlan);\n                                    }\n                                    if (subscriptionPurchase.getLineItems().get(i).getOfferDetails() != null) {\n                                        Map<String, Object> mapOfferDetails = new HashMap<>();\n                                        mapOfferDetails.put(\"basePlanId\",\n                                                subscriptionPurchase.getLineItems().get(i).\n                                                        getOfferDetails().getBasePlanId());\n                                        if (subscriptionPurchase.getLineItems().get(i).\n                                                getOfferDetails().getOfferId() != null) {\n                                            mapOfferDetails.put(\"offerId\",\n                                                    subscriptionPurchase.getLineItems().get(i).\n                                                            getOfferDetails().getOfferId());\n                                        }\n                                        mapSubscriptionPurchaseLineItem.put(\"offerDetails\", mapOfferDetails);\n\n                                    }\n                                    if (subscriptionPurchase.getLineItems().get(i).getDeferredItemReplacement() != null) {\n                                        Map<String, Object> mapDeferredItemReplacement = new HashMap<>();\n                                        mapDeferredItemReplacement.put(\"productId\",\n                                                subscriptionPurchase.getLineItems().get(i).\n                                                        getDeferredItemReplacement().getProductId());\n                                        mapSubscriptionPurchaseLineItem.put(\"deferredItemReplacement\",\n                                                mapDeferredItemReplacement);\n\n                                    }\n                                    if (subscriptionPurchase.getLineItems().get(i).getPrepaidPlan() != null\n                                            && subscriptionPurchase.getLineItems().get(i).\n                                            getPrepaidPlan().getAllowExtendAfterTime() != null) {\n                                        Map<String, Object> mapPrepaidPlan = new HashMap<>();\n                                        mapPrepaidPlan.put(\"allowExtendAfterTime\",\n                                                subscriptionPurchase.getLineItems().get(i).\n                                                        getPrepaidPlan().getAllowExtendAfterTime());\n                                        mapSubscriptionPurchaseLineItem.put(\"prepaidPlan\", mapPrepaidPlan);\n                                    }\n                                    lineItems[i] = mapSubscriptionPurchaseLineItem;\n                                }\n                                mapSubscription.put(\"lineItems\", lineItems);\n                                mapSubscription.put(\"acknowledgementState\",\n                                        subscriptionPurchase.getAcknowledgementState());\n                                mapSubscription.put(\"canceledStateContext\",\n                                        subscriptionPurchase.getCanceledStateContext());\n                                mapSubscription.put(\"kind\",\n                                        subscriptionPurchase.getKind());\n                                mapSubscription.put(\"latestOrderId\",\n                                        subscriptionPurchase.getLatestOrderId());\n                                mapSubscription.put(\"linkedPurchaseToken\",\n                                        subscriptionPurchase.getLinkedPurchaseToken());\n                                mapSubscription.put(\"regionCode\",\n                                        subscriptionPurchase.getRegionCode());\n                                mapSubscription.put(\"subscriptionState\",\n                                        subscriptionPurchase.getSubscriptionState());\n                                mapSubscription.put(\"testPurchase\", null);\n                                mapSubscription.put(\"startTime\",\n                                        subscriptionPurchase.getStartTime());\n                                map.put(\"subscriptionPurchase\", mapSubscription);\n                            } else {\n                                ValidationFailureData failureData = v.getFailureData();\n                                Map<String, Object> mapValidationFailureData = new HashMap<>();\n                                mapValidationFailureData.put(\"status\", failureData.getStatus());\n                                mapValidationFailureData.put(\"description\", failureData.getDescription());\n                                map.put(\"failureData\", mapValidationFailureData);\n                            }\n                            JSONObject resultObject = new JSONObject(map);\n                            UnityPlayer.UnitySendMessage(unityObjectName, VALIDATION_CALLBACK,\n                                    resultObject.toString());\n                        });\n                    }\n                }\n\n                @Override\n                public void onFailure(@NonNull String result, @Nullable Throwable error) {\n                    if (unityObjectName != null) {\n                        UnityPlayer.UnitySendMessage(unityObjectName, ERROR_CALLBACK, result);\n                    }\n                }\n            });\n\n            builder.setInAppValidationResultListener(new PurchaseClient.InAppPurchaseValidationResultListener() {\n                @SuppressLint(\"LongLogTag\")\n                @RequiresApi(api = Build.VERSION_CODES.N)\n                @Override\n                public void onResponse(@Nullable Map<String, ? extends InAppPurchaseValidationResult> result) {\n                    if (unityObjectName != null) {\n                        if (result == null) {\n                            return;\n                        }\n                        result.forEach((k, v) -> {\n                            Map<String, Object> map = new HashMap<>();\n                            Map<String, Object> mapIAP = new HashMap<>();\n//                            JSONObject jsonObject = new JSONObject(map);\n                            map.put(\"token\", k);\n                            map.put(\"success\", v.getSuccess() ? \"true\" : \"false\");\n                            if (v.getSuccess()) {\n                                ProductPurchase productPurchase = v.getProductPurchase();\n\n                                mapIAP.put(\"productId\", productPurchase.getProductId());\n                                mapIAP.put(\"purchaseState\", productPurchase.getPurchaseState());\n                                mapIAP.put(\"kind\", productPurchase.getKind());\n                                mapIAP.put(\"purchaseTimeMillis\", productPurchase.getPurchaseTimeMillis());\n                                mapIAP.put(\"consumptionState\", productPurchase.getConsumptionState());\n                                mapIAP.put(\"developerPayload\", productPurchase.getDeveloperPayload());\n                                mapIAP.put(\"orderId\", productPurchase.getOrderId());\n                                mapIAP.put(\"purchaseType\", productPurchase.getPurchaseType());\n                                mapIAP.put(\"acknowledgementState\", productPurchase.getAcknowledgementState());\n                                mapIAP.put(\"purchaseToken\", productPurchase.getPurchaseToken());\n                                mapIAP.put(\"quantity\", productPurchase.getQuantity());\n                                mapIAP.put(\"obfuscatedExternalAccountId\", productPurchase.getObfuscatedExternalAccountId());\n                                mapIAP.put(\"obfuscatedExternalProfileId\", productPurchase.getObfuscatedExternalProfileId());\n                                mapIAP.put(\"regionCode\", productPurchase.getRegionCode());\n\n\n                                map.put(\"productPurchase\", mapIAP);\n                            } else {\n                                ValidationFailureData failureData = v.getFailureData();\n                                Map<String, Object> mapValidationFailureData = new HashMap<>();\n                                mapValidationFailureData.put(\"status\", failureData.getStatus());\n                                mapValidationFailureData.put(\"description\", failureData.getDescription());\n                                map.put(\"failureData\", mapValidationFailureData);\n                            }\n\n                            JSONObject resultObject = new JSONObject(map);\n                            UnityPlayer.UnitySendMessage(unityObjectName, VALIDATION_CALLBACK, resultObject.toString());\n                        });\n                    }\n                }\n\n                @Override\n                public void onFailure(@NonNull String result, @Nullable Throwable error) {\n                    if (unityObjectName != null) {\n                        UnityPlayer.UnitySendMessage(unityObjectName, ERROR_CALLBACK, result);\n                    }\n                }\n            });\n        }\n    }\n\n\n    public static void startObservingTransactions() {\n        if (purchaseClientInstance != null) {\n            purchaseClientInstance.startObservingTransactions();\n        } else {\n            Log.w(\"AppsFlyer_Connector\", \"[PurchaseConnector]: startObservingTransactions was not called because the purchase client instance is null, please call build() prior to this function.\");\n        }\n    }\n\n    public static void stopObservingTransactions() {\n        if (purchaseClientInstance != null) {\n            purchaseClientInstance.stopObservingTransactions();\n        } else {\n            Log.w(\"AppsFlyer_Connector\", \"[PurchaseConnector]: stopObservingTransactions was not called because the purchase client instance is null, please call build() prior to this function.\");\n        }\n    }\n\n    private static Store mappingEnum(int storeEnum) {\n        switch (storeEnum) {\n            case 0:\n                return Store.GOOGLE;\n            default:\n                return null;\n        }\n    }\n}\n"
  },
  {
    "path": "android-unity-wrapper/unitywrapper/src/main/java/com/appsflyer/unity/PurchaseRevenueBridge.java",
    "content": "package com.appsflyer.unity;\n\nimport android.util.Log;\nimport com.appsflyer.api.InAppPurchaseEvent;\nimport com.appsflyer.api.SubscriptionPurchaseEvent;\nimport com.appsflyer.api.PurchaseClient;\nimport com.appsflyer.api.Store;\nimport com.appsflyer.internal.models.InAppPurchaseValidationResult;\nimport com.appsflyer.internal.models.SubscriptionValidationResult;\nimport com.appsflyer.internal.models.ValidationFailureData;\nimport com.unity3d.player.UnityPlayer;\n\nimport org.json.JSONObject;\nimport org.json.JSONException;\nimport org.json.JSONArray;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Iterator;\n\npublic class PurchaseRevenueBridge {\n    private static final String TAG = \"AppsFlyerUnity\";\n\n    public interface UnityPurchaseRevenueBridge {\n        String getAdditionalParameters(String productsJson, String transactionsJson);\n    }\n\n    private static UnityPurchaseRevenueBridge unityBridge;\n\n    public static void setUnityBridge(UnityPurchaseRevenueBridge bridge) {\n        unityBridge = bridge;\n    }\n\n    public static PurchaseClient.Builder configurePurchaseClient(PurchaseClient.Builder builder) {\n        return builder\n            .setInAppPurchaseEventDataSource(purchaseEvents -> {\n                try {\n                    String eventsJson = new JSONObject(Collections.singletonMap(\"events\", purchaseEvents)).toString();\n                    String response = unityBridge != null ? unityBridge.getAdditionalParameters(eventsJson, \"\") : null;\n                    if (response != null) {\n                        JSONObject json = new JSONObject(response);\n                        Map<String, Object> map = new HashMap<>();\n                        Iterator<String> keys = json.keys();\n                        while (keys.hasNext()) {\n                            String key = keys.next();\n                            map.put(key, json.get(key));\n                        }\n                        return map;\n                    }\n                } catch (JSONException e) {\n                    Log.e(TAG, \"Failed to parse additional params from Unity\", e);\n                }\n                return Collections.emptyMap();\n            })\n            .setSubscriptionPurchaseEventDataSource(purchaseEvents -> {\n                try {\n                    String eventsJson = new JSONObject(Collections.singletonMap(\"events\", purchaseEvents)).toString();\n                    String response = unityBridge != null ? unityBridge.getAdditionalParameters(\"\", eventsJson) : null;\n                    if (response != null) {\n                        JSONObject json = new JSONObject(response);\n                        Map<String, Object> map = new HashMap<>();\n                        Iterator<String> keys = json.keys();\n                        while (keys.hasNext()) {\n                            String key = keys.next();\n                            map.put(key, json.get(key));\n                        }\n                        return map;\n                    }\n                } catch (JSONException e) {\n                    Log.e(TAG, \"Failed to parse additional params from Unity\", e);\n                }\n                return Collections.emptyMap();\n            });\n    }\n}\n"
  },
  {
    "path": "deploy/build_unity_package.sh",
    "content": "#!/bin/bash\n\necho \"Start Build for appsflyer-unity-plugin.unitypackage\"\n\nDEPLOY_PATH=outputs\nUNITY_PATH=\"/Applications/Unity/Unity.app/Contents/MacOS/Unity\"\nPACKAGE_NAME=\"appsflyer-unity-plugin-6.17.91.unitypackage\"\nmkdir -p $DEPLOY_PATH\n\n#move external dependency manager\necho \"moving the external dependency manager to root\"\nmv external-dependency-manager-1.2.183.unitypackage ..\n\n# Temporarily move Tests folder to avoid NUnit compilation errors in batch mode\necho \"Temporarily moving Tests folder...\"\nrm -rf ../Tests_temp ../Tests_temp.meta\nmv ../Assets/AppsFlyer/Tests ../Tests_temp\nmv ../Assets/AppsFlyer/Tests.meta ../Tests_temp.meta 2>/dev/null || true\n\n# Build the .unitypackage\n/Applications/Unity/Hub/Editor/6000.3.1f1/Unity.app/Contents/MacOS/Unity \\\n-gvh_disable \\\n-batchmode \\\n-importPackage external-dependency-manager-1.2.183.unitypackage \\\n-nographics \\\n-logFile create_unity_core.log \\\n-projectPath $PWD/../ \\\n-exportPackage \\\nAssets/AppsFlyer \\\n$PWD/$DEPLOY_PATH/$PACKAGE_NAME \\\n-quit \\\n&& echo \"package exported successfully to outputs/appsflyer-unity-plugin-6.17.91.unitypackage\" \\\n|| echo \"Failed to export package. See create_unity_core.log for more info.\"\n\n# Move Tests folder back\necho \"Moving Tests folder back...\"\nmv ../Tests_temp ../Assets/AppsFlyer/Tests\nmv ../Tests_temp.meta ../Assets/AppsFlyer/Tests.meta 2>/dev/null || true\n\nif [ \"$1\" == \"-p\" ]; then\necho \"moving back the external dependency manager to deploy\"\nmv ../external-dependency-manager-1.2.183.unitypackage .\necho \"removing ./Library\"\nrm -rf ../Library\necho \"removing ./Logs\"\nrm -rf ../Logs\necho \"removing ./Packages\"\nrm -rf ../Packages\necho \"removing ./deploy/create_unity_core.log\"\nrm ./create_unity_core.log\necho \"Moving  $DEPLOY_PATH/$PACKAGE_NAME to root\"\nmv ./outputs/$PACKAGE_NAME ..\necho \"removing ./deploy/outputs\"\nrm -rf ./outputs\necho \"removing ./Assets extra files\"\nrm -rf ../Assets/ExternalDependencyManager\nrm -rf ../Assets/PlayServicesResolver\nrm ../Assets/ExternalDependencyManager.meta\nrm ../Assets/PlayServicesResolver.meta\nelse\necho \"dev mode. No files removed. Run with -p flag for production build.\"\nfi"
  },
  {
    "path": "deploy/strict_mode_build_package.sh",
    "content": "#!/bin/bash\n\necho \"Start Build for appsflyer-unity-plugin.unitypackage. Strict Mode.\"\n\n\n DEPLOY_PATH=outputs\n UNITY_PATH=\"/Applications/Unity/Unity.app/Contents/MacOS/Unity\"\n PACKAGE_NAME=\"appsflyer-unity-plugin-strict-mode-6.17.91.unitypackage\"\n mkdir -p $DEPLOY_PATH\n\n#move external dependency manager\necho \"moving the external dependency manager to root\"\nmv external-dependency-manager-1.2.183.unitypackage ..\n\necho \"Changing AppsFlyerFramework to Strict Mode\"\nsed -i '' 's/AppsFlyerFramework/AppsFlyerFramework\\/Strict/g' ../Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml\necho \"Changing AppsFlyerFramework to Strict Mode. Done.\"\n\necho \"Changing PurchaseConnector to Strict Mode\"\nsed -i '' 's/PurchaseConnector/PurchaseConnector\\/Strict/g' ../Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml\necho \"Changing PurchaseConnector to Strict Mode. Done.\"\n\necho \"Commenting out disableAdvertisingIdentifier\"\nsed -i '' 's/\\[AppsFlyerLib shared\\].disableAdvertisingIdentifier/\\/\\/\\[AppsFlyerLib shared\\].disableAdvertisingIdentifier/g' ../Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm\n\n\necho \"Commenting out waitForATTUserAuthorizationWithTimeoutInterval\"\nsed -i '' 's/\\[\\[AppsFlyerLib shared\\] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval\\];/\\/\\/\\[\\[AppsFlyerLib shared\\] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval\\];/g' ../Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm\necho \"Commenting out functions. Done.\"\n\n# Temporarily move Tests folder to avoid NUnit compilation errors in batch mode\necho \"Temporarily moving Tests folder...\"\nrm -rf ../Tests_temp ../Tests_temp.meta\nmv ../Assets/AppsFlyer/Tests ../Tests_temp\nmv ../Assets/AppsFlyer/Tests.meta ../Tests_temp.meta 2>/dev/null || true\n\n # Build the .unitypackage\n/Applications/Unity/Hub/Editor/6000.3.1f1/Unity.app/Contents/MacOS/Unity \\\n -gvh_disable \\\n -batchmode \\\n -importPackage external-dependency-manager-1.2.183.unitypackage \\\n -nographics \\\n -logFile create_unity_core.log \\\n -projectPath $PWD/../ \\\n -exportPackage \\\n Assets/AppsFlyer \\\n $PWD/$DEPLOY_PATH/$PACKAGE_NAME \\\n -quit \\\n && echo \"package exported successfully to outputs/appsflyer-unity-plugin-strict-mode-6.17.91.unitypackage\" \\\n || echo \"Failed to export package. See create_unity_core.log for more info.\"\n\n# Move Tests folder back\necho \"Moving Tests folder back...\"\nmv ../Tests_temp ../Assets/AppsFlyer/Tests\nmv ../Tests_temp.meta ../Assets/AppsFlyer/Tests.meta 2>/dev/null || true\n\n if [ \"$1\" == \"-p\" ]; then\n echo \"moving back the external dependency manager to deploy\"\n mv ../external-dependency-manager-1.2.183.unitypackage .\n echo \"removing ./Library\"\n rm -rf ../Library\n echo \"removing ./Logs\"\n rm -rf ../Logs\n echo \"removing ./Packages\"\n rm -rf ../Packages\n echo \"removing ./deploy/create_unity_core.log\"\n rm ./create_unity_core.log\n echo \"Moving $DEPLOY_PATH/$PACKAGE_NAME to strict-mode-sdk folder\"\n mv ./outputs/$PACKAGE_NAME ../strict-mode-sdk\n echo \"removing ./deploy/outputs\"\n rm -rf ./outputs\n echo \"removing ./Assets extra files\"\n rm -rf ../Assets/ExternalDependencyManager\n rm -rf ../Assets/PlayServicesResolver\n rm ../Assets/ExternalDependencyManager.meta\n rm ../Assets/PlayServicesResolver.meta\n echo \"Uncomment disableAdvertisingIdentifier\"\n sed -i '' 's/\\/\\/\\[AppsFlyerLib/\\[AppsFlyerLib/g' ../Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm\n\n echo \"Uncomment waitForATTUserAuthorizationWithTimeoutInterval\"\n sed -i '' 's/\\/\\/\\[\\[AppsFlyerLib/\\[\\[AppsFlyerLib/g' ../Assets/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm\n echo \"Uncomment functions. Done.\"\n\n echo \"Changing AppsFlyerFramework back\"\n sed -i '' 's/AppsFlyerFramework\\/Strict/AppsFlyerFramework/g' ../Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml\n echo \"Changing AppsFlyerFramework back. Done.\"\n\n  echo \"Changing PurchaseConnector back\"\n sed -i '' 's/PurchaseConnector\\/Strict/PurchaseConnector/g' ../Assets/AppsFlyer/Editor/AppsFlyerDependencies.xml\n echo \"Changing PurchaseConnector back. Done.\"\n\n else\n echo \"dev mode. No files removed. Run with -p flag for production build.\"\n fi\n"
  },
  {
    "path": "docs/API.md",
    "content": "---\r\ntitle: API reference\r\ncategory: 5f9705393c689a065c409b23\r\nparentDoc: 6370c9e2441a4504d6bca3bd\r\norder: 12\r\nhidden: false\r\n---\r\n\r\nThe list of available methods for this plugin is described below.\r\n- [Android, iOS and Windows API](#android-ios-and-windows-api)\r\n  - [initSDK](#initsdk)\r\n  - [startSDK](#startsdk)\r\n- [Android and iOS API](#android-and-ios-api)\r\n  - [stopSDK](#stopsdk)\r\n  - [isSDKStopped](#issdkstopped)\r\n  - [getSdkVersion](#getsdkversion)\r\n  - [setIsDebug](#setisdebug)\r\n  - [addPushNotificationDeepLinkPath](#addpushnotificationdeeplinkpath)\r\n  - [setCustomerUserId](#setcustomeruserid)\r\n  - [setAppInviteOneLinkID](#setappinviteonelinkid)\r\n  - [setAdditionalData](#setadditionaldata)\r\n  - [setResolveDeepLinkURLs](#setresolvedeeplinkurls)\r\n  - [setOneLinkCustomDomain](#setonelinkcustomdomain)\r\n  - [setCurrencyCode](#setcurrencycode)\r\n  - [setDeepLinkTimeout](#setdeeplinktimeout)\r\n  - [enableTCFDataCollection](#enabletcfdatacollection)\r\n  - [setConsentData](#setconsentdata)\r\n  - [recordLocation](#recordlocation)\r\n  - [anonymizeUser](#anonymizeuser)\r\n  - [getAppsFlyerId](#getappsflyerid)\r\n  - [setMinTimeBetweenSessions](#setmintimebetweensessions)\r\n  - [setHost](#sethost)\r\n  - [setUserEmails *Soon to be deprecated*](#setuseremails-soon-to-be-deprecated)\r\n  - [setPhoneNumber *Soon to be deprecated*](#setphonenumber-soon-to-be-deprecated)\r\n  - [getConversionData](#getconversiondata)\r\n  - [attributeAndOpenStore](#attributeandopenstore)\r\n  - [logAdRevenue](#logadrevenue)\r\n  - [recordCrossPromoteImpression](#recordcrosspromoteimpression)\r\n  - [generateUserInviteLink](#generateuserinvitelink)\r\n  - [setSharingFilterForAllPartners *Deprecated*](#setsharingfilterforallpartners-deprecated)\r\n  - [setSharingFilter *Deprecated*](#setsharingfilter-deprecated)\r\n  - [setSharingFilterForPartners](#setsharingfilterforpartners)\r\n  - [setPartnerData](#setpartnerdata)\r\n- [Android Only API](#android-only-api)\r\n  - [updateServerUninstallToken](#updateserveruninstalltoken)\r\n  - [setImeiData](#setimeidata)\r\n  - [setAndroidIdData](#setandroididdata)\r\n  - [waitForCustomerUserId](#waitforcustomeruserid)\r\n  - [setCustomerIdAndStartSDK](#setcustomeridandstartsdk)\r\n  - [getOutOfStore](#getoutofstore)\r\n  - [setOutOfStore](#setoutofstore)\r\n  - [setCollectAndroidID](#setcollectandroidid)\r\n  - [setCollectIMEI](#setcollectimei)\r\n  - [setIsUpdate](#setisupdate)\r\n  - [setPreinstallAttribution](#setpreinstallattribution)\r\n  - [isPreInstalledApp](#ispreinstalledapp)\r\n  - [handlePushNotifications](#handlepushnotifications)\r\n  - [getAttributionId](#getattributionid)\r\n- [In-App Purchase Validation](#in-app-purchase-validation)\r\n  - [validateAndSendInAppPurchase (V2 - Recommended)](#validateandsendinapppurchase-v2---recommended)\r\n  - [validateAndSendInAppPurchase (Legacy - Deprecated)](#validateandsendinapppurchase-legacy---deprecated)\r\n  - [setCollectOaid](#setcollectoaid)\r\n  - [setDisableAdvertisingIdentifiers](#setdisableadvertisingidentifiers)\r\n  - [setDisableNetworkData](#setdisablenetworkdata)\r\n- [iOS Only API](#ios-only-api)\r\n  - [setDisableCollectAppleAdSupport](#setdisablecollectappleadsupport)\r\n  - [handlePushNotifications(iOS)](#handlepushnotificationsios)\r\n  - [setShouldCollectDeviceName](#setshouldcollectdevicename)\r\n  - [setDisableCollectIAd](#setdisablecollectiad)\r\n  - [setUseReceiptValidationSandbox](#setusereceiptvalidationsandbox)\r\n  - [setUseUninstallSandbox](#setuseuninstallsandbox)\r\n- [In-App Purchase Validation (iOS)](#in-app-purchase-validation-ios)\r\n  - [validateAndSendInAppPurchase (V2 - Recommended) {#validateandsendinapppurchase-v2---recommended-1}](#validateandsendinapppurchase-v2---recommended-validateandsendinapppurchase-v2---recommended-1)\r\n  - [validateAndSendInAppPurchase (Legacy - Deprecated) {#validateandsendinapppurchase-legacy-1}](#validateandsendinapppurchase-legacy---deprecated-validateandsendinapppurchase-legacy-1)\r\n  - [registerUninstall](#registeruninstall)\r\n  - [handleOpenUrl](#handleopenurl)\r\n  - [waitForATTUserAuthorizationWithTimeoutInterval](#waitforattuserauthorizationwithtimeoutinterval)\r\n  - [disableSKAdNetwork](#disableskadnetwork)\r\n  - [setLanguage](#setlanguage)\r\n  - [disableIDFVCollection](#disableidfvcollection)\r\n- [IAppsFlyerConversionData](#iappsflyerconversiondata)\r\n  - [onConversionDataSuccess](#onconversiondatasuccess)\r\n  - [onConversionDataFail](#onconversiondatafail)\r\n  - [onAppOpenAttribution](#onappopenattribution)\r\n  - [onAppOpenAttributionFailure](#onappopenattributionfailure)\r\n- [IAppsFlyerUserInvite](#iappsflyeruserinvite)\r\n  - [onInviteLinkGenerated](#oninvitelinkgenerated)\r\n  - [onInviteLinkGeneratedFailure](#oninvitelinkgeneratedfailure)\r\n  - [onOpenStoreLinkGenerated](#onopenstorelinkgenerated)\r\n- [IAppsFlyerValidateReceipt](#iappsflyervalidatereceipt)\r\n  - [didFinishValidateReceipt](#didfinishvalidatereceipt)\r\n- [IAppsFlyerValidateAndLog](#iappsflyervalidateandlog)\r\n  - [onValidateAndLogComplete](#onvalidateandlogcomplete)\r\n  - [onValidateAndLogFailure](#onvalidateandlogfailure)\r\n- [Events](#events)\r\n  - [onRequestResponse](#onrequestresponse)\r\n  - [onInAppResponse](#oninappresponse)\r\n  - [onDeepLinkReceived](#ondeeplinkreceived)\r\n\r\n\r\n---\r\n\r\n## Android, iOS and Windows API\r\n\r\n### initSDK \r\n**`void initSDK(string devKey, string appID, MonoBehaviour gameObject)`**\r\n\r\nInitialize the AppsFlyer SDK with the devKey and appID.\r\nThe dev key is required for all apps and the appID is required only for iOS. \r\nIf you app is for Android only pass null for the appID.\r\n\r\n\r\n| parameter               | type                        | description  |\r\n| -----------             |-----------------------------|--------------|\r\n| `dev_key`               | `string`                    | AppsFlyer's Dev-Key, which is accessible from your AppsFlyer account under 'App Settings' in the dashboard.                  |\r\n| `app_id`                | `string`                    | Your app's Apple ID. |\r\n| `gameObject` (optional) | `MonoBehaviour`             |  The game object containing the IAppsFlyerConversionData interface.           |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.initSDK(\"dev_key\", \"app_id\"); // without deeplinking\r\nAppsFlyer.initSDK(\"dev_key\", \"app_id\", this); // with deeplinking\r\n```\r\n\r\n**Note :** You only need to implement the SDK **with deeplinking** if you are using the `IAppsFlyerConversionData` interface.\r\n\r\n---\r\n\r\n### startSDK\r\n**`void startSDK()`**\r\n    \r\nOnce this API is invoked the SDK will start,  sessions will be immediately sent, and all background foreground transitions will record a session.\r\n\r\n*Example:*\r\n\r\n```c#\r\n AppsFlyer.startSDK();\r\n```\r\n\r\n---\r\n\r\n## Android and iOS API\r\n\r\n### stopSDK \r\n**`void stopSDK(bool isSDKStopped)`**\r\n\r\nIn some extreme cases you might want to shut down all SDK functions due to legal and privacy compliance. This can be achieved with the stopSDK API. Once this API is invoked, our SDK no longer communicates with our servers and stops functioning.\r\n\r\nThere are several different scenarios for user opt-out. We highly recommend following the exact instructions for the scenario, that is relevant for your app.\r\n\r\nIn any event, the SDK can be reactivated by calling the same API, by passing false.\r\n\r\n **Important :**\r\nDo not call startSDK() if stopSDK() is set to true.\r\n\r\nTo restart SDK functions again, use the following API:\r\n\r\n`AppsFlyer.stopSDK(false);`\r\n\r\n **Warning**\r\nUse the stopSDK API only in cases where you want to fully ignore the user's SDK functions. Using this API SEVERELY impacts your attribution, data collection and deep linking mechanism.\r\n\r\n| parameter       | type    | description                                          |\r\n| -------------   |---------|----------------------------                          |\r\n| `isSDKStopped`  | `bool`  | True if the SDK is stopped (default value is false). |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.stopSDK(true);\r\n```\r\n\r\n---\r\n\r\n### isSDKStopped\r\n**`bool isSDKStopped()`**\r\n\r\nWas the stopSDK(boolean) API set to `true`.\r\n\r\n*Example:*\r\n\r\n```c#\r\nif (!AppsFlyer.isSDKStopped())\r\n{\r\n  \r\n}\r\n```\r\n\r\n---\r\n\r\n### getSdkVersion \r\n**`string getSdkVersion()`**\r\n\r\nGet the AppsFlyer SDK version used in the app.\r\n\r\n*Example:*\r\n\r\n```c#\r\nstring version = AppsFlyer.getSdkVersion();\r\n```\r\n\r\n---\r\n\r\n### setIsDebug\r\n**`void setIsDebug(bool shouldEnable)`**\r\n\r\nEnables Debug logs for the AppsFlyer SDK.\r\n\r\n **Warning**\r\nOnly set to true in development / debug.\r\n\r\n| parameter      | type   | description                                 |\r\n| -----------    |------- |---------------------------------------------|\r\n| `shouldEnable` | `bool` | True if debug mode is on (default is false) |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setIsDebug(true);\r\n```\r\n\r\n---\r\n\r\n### addPushNotificationDeepLinkPath\r\n\r\n**`void addPushNotificationDeepLinkPath(params string[] paths)`**\r\n\r\nAdds array of keys, which are used to compose key path to resolve deeplink from push notification payload.\r\n\r\n| parameter      | type   | description                                 |\r\n| -----------    |------- |---------------------------------------------|\r\n| `paths` | `string[]` | array of strings that represent the key path to the deeplink in the push notification payload |\r\n\r\n*Example:*\r\n\r\n**Usage example**  \r\nBasic configuration:\r\n\r\n```c#\r\nAppsFlyer.addPushNotificationDeepLinkPath(\"af_push_link\")\r\n```\r\n\r\nThis call matches the following payload structure:\r\n\r\n```json\r\n{\r\n  \"af_push_link\": \"https://yourdeeplink2.onelink.me\"\r\n}\r\n```\r\n\r\nֿAdvanced configuration:\r\n\r\n```c#\r\nstring[] paths = {\"deeply\", \"nested\", \"deep_link\"};\r\nAppsFlyer.addPushNotificationDeepLinkPath(paths);\r\n```\r\n\r\nThis call matches the following payload structure:\r\n\r\n```json\r\n{\r\n  \"deeply\": {\r\n      \"nested\": {\r\n          \"deep_link\": \"https://yourdeeplink2.onelink.me\"\r\n      }\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n### setCustomerUserId\r\n**`void setCustomerUserId(string id)`**\r\n\r\nSetting your own Custom ID enables you to cross-reference your own unique ID with AppsFlyer’s user ID and the other devices’ IDs. This ID is available in AppsFlyer CSV reports along with postbacks APIs for cross-referencing with your internal IDs.\r\n\r\n| parameter | type     | description     |\r\n| --------- |--------- |--------------   |\r\n| `id`      | `string` | custom user ID  |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setCustomerUserId(\"custom_user_id\");\r\n```\r\n\r\n---\r\n\r\n### setAppInviteOneLinkID \r\n**`void setAppInviteOneLinkID(string oneLinkId)`**\r\n\r\nSet the OneLink ID that should be used for User-Invite-API\r\nThe link that is generated for the user invite will use this OneLink as the base link.\r\n\r\n| parameter   | type     | description                            |\r\n| ----------- |--------- |----------------------------------------|\r\n| `oneLinkId` | `string` | OneLink ID for User-Invite attribution |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setAppInviteOneLinkID(\"abcd\");\r\n```\r\n\r\n---\r\n\r\n### setAdditionalData\r\n**`void setAdditionalData(Dictionary<string, string> customData)`**\r\n\r\nThe setAdditionalData API is required to integrate on the SDK level with several external partner platforms, including Segment, Adobe and Urban Airship. Use this API only if the integration article of the platform specifically states setAdditionalData API is needed. \r\n\r\n| parameter    | type                         | description     |\r\n| -----------  |----------------------------- |--------------   |\r\n| `customData` | `Dictionary<string, string>` | additional data |\r\n\r\n*Example:*\r\n\r\n```c#\r\nDictionary<string, string> customData = new Dictionary<string, string>();\r\ncustomData.Add(\"custom1\", \"someData\");\r\nAppsFlyer.setAdditionalData(customData);\r\n```\r\n---\r\n\r\n### setResolveDeepLinkURLs\r\n**`void setResolveDeepLinkURLs(params string[] urls)`**\r\n\r\nIf you are using OneLinks which support Android App Links and wrapping them with a 3rd Party Universal Link, you can use the setResolveDeepLinkURLs API to notify the AppsFlyer SDK which click domains that invoke the app should be resolved by the SDK and have the underlying OneLink extracted from them. This will allow you to maintain deep linking and attribution while wrapping the OneLink with a 3rd party Universal Link. Make sure to call this API before SDK initialization.\r\n\r\n| parameter | type              | description   |\r\n| ----------|-------------------|-------------- |\r\n| `urls`    | `params string[]` | array of urls |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setResolveDeepLinkURLs(\"test.com\", \"test2.ca\");\r\n```\r\n\r\n---\r\n\r\n### setOneLinkCustomDomain \r\n**`void setOneLinkCustomDomain(params string[] domains)`**\r\n    \r\nAdvertisers can use this method to set vanity onelink domains.\r\n\r\n| parameter  | type              | description             |\r\n| ---------- | ----------------- |-------------------------|\r\n| `domains`  | `params string[]` | array of custom domains |\r\n\r\n*Example:*\r\n\r\n```c#\r\n AppsFlyer.setOneLinkCustomDomain(\"test.domain\", \"test2.domain\");\r\n```\r\n\r\n---\r\n\r\n### setCurrencyCode \r\n**`void setCurrencyCode(string currencyCode)`**\r\n\r\nSetting user local currency code for in-app purchases.\r\nThe currency code should be a 3 character ISO 4217 code. (default is USD).\r\nYou can set the currency code for all events by calling the following method.\r\n\r\n| parameter      | type     | description                                 |\r\n| -----------    |----------|---------------------------------------------|\r\n| `currencyCode` | `string` | 3 character ISO 4217 code. (default is USD) |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setCurrencyCode(\"GBP\");\r\n```\r\n\r\n---\r\n\r\n---\r\n\r\n### setDeepLinkTimeout \r\n**`void setDeepLinkTimeout(long deepLinkTimeout)`**\r\n\r\nSetting the deepLink timeout value that should be used for DDL.\r\nIf you want to use it, set it before the DDL setting.\r\n\r\n| parameter          | type     | description      |\r\n| ------------------ |----------|------------------|\r\n| `deepLinkTimeout`  | `long`   | in milliseconds  |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setDeepLinkTimeout(2000);\r\n```\r\n\r\n---\r\n\r\n### enableTCFDataCollection \r\n**`void enableTCFDataCollection(bool shouldCollectTcfData)`**\r\n\r\nCalling enableTCFDataCollection(true) will enable collecting and sending any TCF related data.\r\nCalling enableTCFDataCollection(false) will disable the collection of TCF related data and from sending it.\r\n\r\n| parameter                | type     | description                     |\r\n| ------------------------ |----------|-------------------------------- |\r\n| `shouldCollectTcfData`   | `bool`   | true to enable data collection  |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.enableTCFDataCollection(true);;\r\n```\r\n\r\n---\r\n\r\n### setConsentData \r\n**`void setConsentData(AppsFlyerConsent appsFlyerConsent)`**\r\n\r\nSets or updates the user consent data related to GDPR and DMA regulations for advertising and data usage purposes within the application.\r\n\r\n| parameter                   | type                | description                                                           |\r\n| --------------------------- |----------           |------------------------------------ |\r\n| `appsFlyerConsent`          | `AppsFlyerConsent`  | Instance of AppsFlyerConsent class  |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyerConsent consent = new AppsFlyerConsent(true, false, false, false);\r\nAppsFlyer.setConsentData(consent);\r\n```\r\n\r\n---\r\n\r\n### recordLocation\r\n**`void recordLocation(double latitude, double longitude)`**\r\n\r\nManually record the location of the user.\r\n\r\n| parameter   | type     | description       |\r\n| ----------- |--------- |--------------     |\r\n| `latitude`  | `double` | latitude of user  |\r\n| `longitude` | `double` | longitude of user |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.recordLocation(40.7128, 74.0060);\r\n```\r\n\r\n---\r\n\r\n### anonymizeUser\r\n**`void anonymizeUser(bool shouldAnonymizeUser)`**\r\n\r\nAppsFlyer provides you with a method to anonymize specific user identifiers in AppsFlyer analytics. This method complies with the latest privacy requirements and complies with Facebook data and privacy policies. Default is NO, meaning no anonymization is performed by default.\r\nUse this API during the SDK Initialization to explicitly anonymize a user's installs, events and sessions.\r\nYou can cancel anonymization by calling anonymizeUser again, set to false.\r\n\r\n**Warning**\r\nAnonymizing users SEVERELY impacts your attribution information. Use this option ONLY for regions which legally prevents you from collecting your users' information.\r\n\r\n| parameter             | type   | description                   |\r\n| --------------------  |--------|-------------------------------|\r\n| `shouldAnonymizeUser` | `bool` | true to perform anonymization |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.anonymizeUser(true);\r\n```\r\n\r\n---\r\n\r\n### getAppsFlyerId \r\n**`string getAppsFlyerId()`**\r\n\r\nAppsFlyer's unique device ID is created for every new install of an app. Use the following API to obtain AppsFlyer’s Unique ID.\r\n\r\n*Example:*\r\n\r\n```c#\r\nstring uid = AppsFlyer.getAppsFlyerId(); \r\n```\r\n\r\n---\r\n\r\n### setMinTimeBetweenSessions \r\n**`void setMinTimeBetweenSessions(int seconds)`**\r\n\r\nBy default, at least 5 seconds must lapse between 2 app launches to count as separate 2 sessions (more about counting sessions). However, you can use the following API to set your custom value for the minimum required time between sessions.\r\n\r\n**Note:** Setting a high value to the custom time between launches may badly impact APIs relying on sessions data, such as deep linking.\r\n\r\n| parameter   | type   | description                                  |\r\n| ----------- |------- |--------------------------------------------- |\r\n| `seconds`   | `int`  | time between sessions (default is 5 seconds) |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setMinTimeBetweenSessions(4);\r\n```\r\n\r\n---\r\n\r\n### setHost\r\n**`void setHost(string hostPrefixName, string hostName)`**\r\n\r\nSet a custom host.\r\n\r\n| parameter        | type      | description  |\r\n| -----------      |---------- |--------------|\r\n| `hostPrefixName` | `string`  |              |\r\n| `hostName`       | `string`  |              |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setHost(\"hostPrefixName\",\"hostName\");\r\n```\r\n\r\n---\r\n\r\n### setUserEmails *Soon to be deprecated*\r\n\r\n**`void setUserEmails(EmailCryptType cryptMethod, params string[] emails)`**\r\n\r\nSet the user emails and encrypt them.\r\n\r\ncryptMethod Encryption methods:\r\nEmailCryptType.EmailCryptTypeSHA256\r\nEmailCryptType.EmailCryptTypeNone\r\n\r\n\r\n| parameter     | type              | description               |\r\n| -----------   |-------------------|---------------------------|\r\n| `cryptMethod` | `EmailCryptType`  | none, or sha256 |\r\n| `emails`      | `params string[]` | list of emails            |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setUserEmails(EmailCryptType.EmailCryptTypeSHA256, \"test1@test1.com\", \"test2@test2.com\");\r\n```\r\n\r\n---\r\n\r\n### setPhoneNumber *Soon to be deprecated*\r\n**`void setPhoneNumber(string phoneNumber)`**\r\n\r\nSet the user phone number.\r\n\r\n\r\n| parameter     | type              | description               |\r\n| -----------   |-------------------|---------------------------|\r\n| `phoneNumber` | `string`  |  |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setPhoneNumber(\"4166358181\");\r\n```\r\n\r\n---\r\n\r\n### getConversionData\r\n**`void getConversionData(string objectName);`**\r\n\r\nRegister a Conversion Data Listener.\r\nAllows the developer to access the user attribution data in real-time for every new install, directly from the SDK level.\r\nBy doing this you can serve users with personalized content or send them to specific activities within the app,\r\nwhich can greatly enhance their engagement with your app.\r\n\r\nGet the callbacks by implementing the IAppsFlyerConversionData interface.\r\n\r\n| parameter    | type     | description                                             |\r\n| -----------  |----------|-------------------------------------------------------- |\r\n| `objectName` | `string` | game object with the IAppsFlyerConversionData interface |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.getConversionData(gameObject.name);\r\n```\r\n\r\n---\r\n\r\n### attributeAndOpenStore\r\n**`void attributeAndOpenStore(string appID, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject)`**\r\n\r\nUse the following API to attribute the click and launch the app store's app page.\r\n\r\nGet the callbacks by implementing the IAppsFlyerUserInvite interface.\r\n\r\n| parameter     | type                         | description                                         |\r\n| -----------   |----------------------------- |-----------------------------------------------------|\r\n| `appID`       | `string`                     |                                                     |\r\n| `campaign`    | `string`                     |                                                     |\r\n| `userParams`  | `Dictionary<string, string> `|                                                     |\r\n| `gameObject`  | `MonoBehaviour`              | game object with the IAppsFlyerUserInvite interface |\r\n\r\n*Example:*\r\n\r\n```c#\r\nDictionary<string, string> parameters = new Dictionary<string, string>();\r\nparameters.Add(\"af_sub1\", \"val\");\r\nparameters.Add(\"custom_param\", \"val2\");\r\nAppsFlyer.attributeAndOpenStore(\"123456789\", \"test campaign\", parameters, this);\r\n```\r\n\r\n---\r\n\r\n### logAdRevenue\r\n**`void logAdRevenue(AFAdRevenueData adRevenueData, Dictionary<string, string> additionalParameters)`**\r\n\r\nLogs ad revenue data along with additional parameters if provided.\r\n\r\n| parameter               | type                         | description                                         |\r\n| -------------------     |----------------------------- |-----------------------------------------------------|\r\n| `adRevenueData`         | `AFAdRevenueData`            |  Instance of AFAdRevenueData containing ad revenue information                                                   |\r\n| `additionalParameters`  | `Dictionary<string, string> `|  An optional map of additional parameters to be logged with ad revenue data                                                  |\r\n\r\n*Example:*\r\n\r\n```c#\r\nDictionary<string, string> parameters = new Dictionary<string, string>();\r\nparameters.Add(\"value1\", \"5\");\r\nparameters.Add(AdRevenueScheme.COUNTRY, \"USA\");\r\nvar logRevenue = new AFAdRevenueData(\"monetizationNetworkEx\", MediationNetwork.GoogleAdMob, \"USD\", 0.99);\r\nAppsFlyer.logAdRevenue(logRevenue, parameters);\r\n```\r\n\r\n---\r\n\r\n### recordCrossPromoteImpression \r\n**`void recordCrossPromoteImpression(string appID, string campaign);`**\r\n\r\nTo attribute an impression use the following API call.\r\nMake sure to use the promoted App ID as it appears within the AppsFlyer dashboard.\r\n\r\n| parameter    | type      | description  |\r\n| -----------  |-----------|--------------|\r\n| `appID`      | `string`  | appID        |\r\n| `campaign`   | `string`  | campaign     |\r\n| `params`     | `Dictionary<string, string>`    | additional params     |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nDictionary<string, string> parameters = new Dictionary<string, string>();\r\nparameters.Add(\"af_sub1\", \"val\");\r\nparameters.Add(\"custom_param\", \"val2\");\r\nAppsFlyer.recordCrossPromoteImpression(\"appID\", \"campaign\", parameters);\r\n```\r\n\r\n---\r\n\r\n### generateUserInviteLink\r\n**`void generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject)`**\r\n\r\nThe LinkGenerator class builds the invite URL according to various setter methods which allow passing on additional information on the click.\r\nSee - https://support.appsflyer.com/hc/en-us/articles/115004480866-User-invite-attribution-\r\n\r\n\r\n| parameter    | type                         | description                                         |\r\n| -----------  |----------------------------- |-----------------------------------------------------|\r\n| `parameters` | `Dictionary<string, string>` |                                                     |\r\n| `gameObject` | `MonoBehaviour`              | game object with the IAppsFlyerUserInvite interface |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.generateUserInviteLink(params, this);\r\n```\r\n\r\n---\r\n\r\n### setSharingFilterForAllPartners *Deprecated*\r\n**`void setSharingFilterForAllPartners()`** \r\n\r\nUsed by advertisers to exclude all networks/integrated partners from getting data.\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setSharingFilterForAllPartners();\r\n```\r\n\r\n---\r\n\r\n### setSharingFilter *Deprecated*\r\n**`void setSharingFilter(params string[] partners)`** \r\n\r\n\r\n Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.\r\n\r\n\r\n| parameter    | type                         | description                                         |\r\n| -----------  |----------------------------- |-----------------------------------------------------|\r\n| `partners` | `params string[] partners` | partners to exclude from getting data                                                    |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setSharingFilter(\"googleadwords_int\",\"snapchat_int\",\"doubleclick_int\");\r\n```\r\n\r\n---\r\n\r\n### setSharingFilterForPartners \r\n**`void setSharingFilterForPartners(params string[] partners)`** \r\n\r\n\r\n Used by advertisers to set some (one or more) networks/integrated partners to exclude from getting data.\r\n\r\n\r\n| parameter    | type                         | description                                         |\r\n| -----------  |----------------------------- |-----------------------------------------------------|\r\n| `partners` | `params string[] partners` | partners to exclude from getting data                                                    |\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.setSharingFilterForPartners(\"partner1_int\"); // Single partner\r\nAppsFlyer.setSharingFilterForPartners(\"partner1_int\", \"partner2_int\"); // Multiple partners\r\nAppsFlyer.setSharingFilterForPartners(\"all\"); // All partners\r\nAppsFlyer.setSharingFilterForPartners(\"\"); // Reset list (default)\r\nAppsFlyer.setSharingFilterForPartners(); // Reset list (default)\r\n```\r\n\r\n---\r\n\r\n### setPartnerData\r\n**`void setPartnerData(string partnerID, params string[] partnerInfo)`** \r\n\r\nAllows sending custom data for partner integration purposes.\r\n\r\n| parameter    | type                         |description       |\r\n| -----------  |------------------------------| -----------------------------------------|\r\n| `partnerID` | `string` | ID of the partner (usually suffixed with \"_int\").|\r\n|`partnerInfo` | `params string[]` | Customer data, depends on the integration configuration with the specific partner. |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n   Dictionary<string, string> partnerInfo = new Dictionary<string, string>();\r\n        partnerInfo.Add(\"puid\", \"1234567890\");\r\n        AppsFlyer.setPartnerData(\"partner_test\", partnerInfo);\r\n```\r\n\r\n---- \r\n\r\n## Android Only API\r\n  \r\n### updateServerUninstallToken\r\n**`void updateServerUninstallToken(string token)`**\r\n \r\n Manually pass the Firebase Device Token for Uninstall measurement.\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `token`     | `string`  | Firebase FCM token |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.updateServerUninstallToken(\"token\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setImeiData \r\n**`void setImeiData(string imei)`**\r\n \r\nBy default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat (4.4)\r\nand the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).\r\nUse this API to explicitly send IMEI to AppsFlyer.\r\n\r\n\r\n| parameter   | type     | description   |\r\n| ----------- |----------|-------------- |\r\n| `imei`      | `string` | device's IMEI |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setImeiData(\"imei\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setAndroidIdData\r\n**`void setAndroidIdData(string androidId)`**\r\n \r\nBy default, IMEI and Android ID are not collected by the SDK if the OS version is higher than KitKat(4.4)and the device contains Google Play Services(on SDK versions 4.8.8 and below the specific app needed GPS).\r\nUse this API to explicitly send Android ID to AppsFlyer.\r\n\r\n| parameter   | type     | description          |\r\n| ----------- | ---------|--------------------- |\r\n| `androidId` | `string` | device's Android ID  |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setAndroidIdData(\"androidId\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### waitForCustomerUserId \r\n**`void waitForCustomerUserId(bool wait)`**\r\n \r\nIt is possible to delay the SDK Initialization until the customerUserID is set.\r\nThis feature makes sure that the SDK doesn't begin functioning until the customerUserID is provided.\r\nIf this API is used, all in-app events and any other SDK API calls are discarded, until the customerUserID is provided.\r\n\r\n\r\n| parameter   | type    | description                                         |\r\n| ----------  |-------- |-----------------------------------------------------|\r\n| `wait`      | `bool`  | True if you want the SDK to wait for customerUserID |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.waitForCustomerUserId(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setCustomerIdAndStartSDK\r\n\r\n**`void setCustomerIdAndStartSDK(string id)`**\r\n\r\n> ⚠️ Before calling this method, the method [`waitForCustomerUserId`](#waitforcustomeruserid) must be called\r\n\r\nUse this API to provide the SDK with the relevant customer user id and trigger the SDK to begin its normal activity.\r\n\r\n| parameter   | type      | description             |\r\n| ----------- |---------- |------------------------ |\r\n| `id`        | `string`  | Customer ID for client. |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCustomerIdStartSDK(\"id\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### getOutOfStore \r\n **`string getOutOfStore()`**\r\n \r\n Get the current AF_STORE value.\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        string af_store = AppsFlyer.getOutOfStore();\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### setOutOfStore \r\n **`void setOutOfStore(string sourceName)`**\r\n \r\n Manually set the AF_STORE value.\r\n\r\n| parameter    | type      | description  |\r\n| -----------  |---------- |--------------|\r\n| `sourceName` | `string`  |              |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setOutOfStore(\"sourceName\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### setCollectAndroidID\r\n **`void setCollectAndroidID(bool isCollect)`**\r\n\r\nOpt-out of collection of Android ID.\r\nIf the app does NOT contain Google Play Services, Android ID is collected by the SDK.\r\nHowever, apps with Google play services should avoid Android ID collection as this is in violation of the Google Play policy.\r\n \r\n| parameter   | type     | description  |\r\n| ----------- |--------- |--------------|\r\n| `isCollect` | `bool`   |              |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCollectAndroidID(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n\r\n ### setCollectIMEI\r\n **`void setCollectIMEI(bool isCollect)`**\r\n \r\nOpt-out of collection of IMEI.\r\nIf the app does NOT contain Google Play Services, device IMEI is collected by the SDK.\r\nHowever, apps with Google play services should avoid IMEI collection as this is in violation of the Google Play policy.\r\n\r\n| parameter          | type                        | description  |\r\n| -----------        |-----------------------------|--------------|\r\n| `isCollect`        | `bool`                      |              |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCollectIMEI(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### setIsUpdate\r\n **`void setIsUpdate(bool isUpdate)`**\r\n \r\nManually set that the application was updated.\r\n\r\n| parameter   | type    | description             |\r\n| ----------- |-------- |-------------------------|\r\n| `isUpdate`  | `bool`  | true if app was updated |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setIsUpdate(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### setPreinstallAttribution\r\n **`void setPreinstallAttribution(string mediaSource, string campaign, string siteId)`**\r\n \r\n Specify the manufacturer or media source name to which the preinstall is attributed.\r\n\r\n| parameter      | type     | description                                                   |\r\n| -----------    |----------|---------------------------------------------------------------|\r\n| `mediaSource`  | `string` | Manufacturer or media source name for preinstall attribution. |\r\n| `campaign`     | `string` | Campaign name for preinstall attribution.                     |\r\n| `siteId`       | `string` | Site ID for preinstall attribution.                           |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setPreinstallAttribution(\"mediaSource\", \"campaign\", \"siteId\");\r\n#endif\r\n```\r\n\r\n\r\n---\r\n\r\n ### isPreInstalledApp\r\n **`bool isPreInstalledApp()`**\r\n \r\nBoolean indicator for preinstall by Manufacturer.\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        if (AppsFlyer.isPreInstalledApp())\r\n        {\r\n\r\n        }\r\n#endif\r\n```\r\n---\r\n\r\n### handlePushNotifications\r\n\r\n**`void handlePushNotifications()`**\r\nWhen the handlePushNotifications API is called push notifications will be recorded.\r\n\r\n*Example:*\r\n\r\n```c#\r\nAppsFlyer.handlePushNotifications();\r\n```\r\n\r\n---\r\n\r\n\r\n### getAttributionId\r\n**`string getAttributionId()`**\r\n \r\nGet the Facebook attribution ID, if one exists.\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        string attributionId = AppsFlyer.getAttributionId();\r\n#endif\r\n```\r\n\r\n\r\n---\r\n\r\n## In-App Purchase Validation\r\n\r\nAppsFlyer provides two versions of the `validateAndSendInAppPurchase` method:\r\n\r\n- **V2 (Recommended)**: Uses structured data classes (`AFPurchaseDetailsAndroid`/`AFSDKPurchaseDetailsIOS`) for better type safety and cleaner code\r\n- **Legacy**: Uses individual string parameters (deprecated, maintained for backward compatibility)\r\n\r\n### validateAndSendInAppPurchase (V2 - Recommended)\r\n**`void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)`**\r\n \r\nAPI for server verification of in-app purchases (V2).\r\nAn af_purchase event with the relevant values will be automatically sent if the validation is successful.\r\n\r\n\r\n| parameter                    | type                         | description                                        |\r\n| -----------                  |------------------------------|----------------------------------------------------|\r\n| `details`                    | `AFPurchaseDetailsAndroid`   | Instance of AFPurchaseDetailsAndroid class |\r\n| `purchaseAdditionalDetails`  | `Dictionary<string, string>` | Additional parameters to be sent with the purchase |\r\n| `gameObject`                 | `MonoBehaviour`              | Game object for the callbacks to be sent           |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AFPurchaseDetailsAndroid details = new AFPurchaseDetailsAndroid(AFPurchaseType.Subscription, \r\n        \"token\", \"productId\");\r\n        \r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        details, \r\n        null, \r\n        this);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### validateAndSendInAppPurchase (Legacy - Deprecated)\r\n**`void validateAndSendInAppPurchase(string publicKey, string signature, string purchaseData, string price, string currency, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`**\r\n \r\n**⚠️ Deprecated:** This legacy API is deprecated. Use the V2 version with `AFPurchaseDetailsAndroid` instead. This method is maintained for backward compatibility only.\r\nAPI for server verification of in-app purchases.\r\nAn af_purchase event with the relevant values will be automatically sent if the validation is successful.\r\n\r\n\r\n| parameter              | type     | description  |\r\n| -----------            |----------|--------------|\r\n| `publicKey`            | `string` | License Key obtained from the Google Play Console. |\r\n| `signature`            | `string` | data.INAPP_DATA_SIGNATURE.                         |\r\n| `purchaseData`         | `string` | data.INAPP_PURCHASE_DATA                           |\r\n| `price`                | `string` | Purchase price                                     |\r\n| `currency`             | `string` | Purchase currency                                   |\r\n|`additionalParameters`  | `Dictionary<string, string>` | Parameters to be sent with the purchase |\r\n| `gameObject`           | `MonoBehaviour` | Game object for the callbacks to be sent   |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        \"publicKey\", \r\n        \"signature\", \r\n        \"purchaseData\", \r\n        \"price\", \r\n        \"currency\", \r\n        null, \r\n        this);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setCollectOaid\r\n**`void setCollectOaid(boolean isCollect)`**\r\n\r\n    setCollectOaid\r\n\r\n    You must include the appsflyer oaid library for this api to work.\r\n\r\n| parameter   | type    | description             |\r\n| ----------- |-------- |-------------------------|\r\n| `isCollect` | `bool`  | true to allow oaid collection |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCollectOaid(true);\r\n#endif\r\n```\r\n\r\n---\r\n    \r\n### setDisableAdvertisingIdentifiers \r\n**`void setDisableAdvertisingIdentifiers(boolean disable)`**\r\n\r\n    setDisableAdvertisingIdentifiers\r\n\r\n    Disables collection of various Advertising IDs by the SDK. This includes Google Advertising ID (GAID), OAID and Amazon Advertising ID (AAID)\r\n\r\n| parameter   | type    | description             |\r\n| ----------- |-------- |-------------------------|\r\n| `disable` | `bool`  | true to disable|\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setDisableAdvertisingIdentifiers(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n---\r\n    \r\n### setDisableNetworkData\r\n**`void setDisableNetworkData(boolean disable)`**\r\n\r\n    setDisableNetworkData\r\n\r\n    Use to opt-out of collecting the network operator name (carrier) and sim operator name from the device.\r\n\r\n| parameter   | type    | description             |\r\n| ----------- |-------- |-------------------------|\r\n| `disable` | `bool`  | true to opt-out|\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setDisableNetworkData(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n##  iOS Only API\r\n           \r\n### setDisableCollectAppleAdSupport \r\n**`void setDisableCollectAppleAdSupport(bool disable)`**\r\n \r\nAppsFlyer SDK collects Apple's `advertisingIdentifier` if the `AdSupport.framework` is included in the SDK.\r\nYou can disable this behavior by setting the following property to true.\r\n\r\n| parameter      | type     | description  |\r\n| -----------    |----------|--------------|\r\n| `disable`      | `bool`   |              |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setDisableCollectAppleAdSupport(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### handlePushNotifications(iOS)\r\n\r\n**`void handlePushNotification(Dictionary<string, string> pushPayload)`**\r\nWhen the handlePushNotifications API is called from a service that is swizzling, like Firebase, the push notifications payload will be handled by the AppsflyerSDK.\r\n\r\n| parameter     | type                         | description                   |\r\n| --------------|------------------------------|-------------------------------|\r\n| `pushPayload` | `Dictionary<string, string>` | the push notification payload |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    // e.Message.Data = push notification payload\r\n    var dataDict = new Dictionary<string, string>(e.Message.Data);\r\n    AppsFlyeriOS.handlePushNotification(dataDict);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setShouldCollectDeviceName\r\n**`void setShouldCollectDeviceName(bool shouldCollectDeviceName)`**\r\n \r\nSet this flag to true, to collect the current device name(e.g. \"My iPhone\"). Default value is false.\r\n        \r\n| parameter                 | type      | description  |\r\n| ----------------------    |---------- |--------------|\r\n| `shouldCollectDeviceName` | `bool`    |              |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setShouldCollectDeviceName(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n ### setDisableCollectIAd\r\n **`void setDisableCollectIAd(bool disableCollectIAd)`**\r\n \r\nOpt-out for Apple Search Ads attributions.\r\n\r\n| parameter           | type     | description  |\r\n| -----------         |----------|--------------|\r\n| `disableCollectIAd` | `bool`   |              |\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setDisableCollectIAd(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setUseReceiptValidationSandbox\r\n**`void setUseReceiptValidationSandbox(bool useReceiptValidationSandbox)`**\r\n \r\n\r\nIn app purchase receipt validation Apple environment(production or sandbox). The default value is false.\r\n\r\n| parameter                     | type      | description                                  |\r\n| ----------------------------  |---------- |--------------------------------------------- |\r\n| `useReceiptValidationSandbox` | `bool`    | true if In app purchase is done with sandbox |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setUseReceiptValidationSandbox(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setUseUninstallSandbox \r\n**`void setUseUninstallSandbox(bool useUninstallSandbox)`**\r\n \r\nSet this flag to test uninstall on Apple environment(production or sandbox). The default value is false.\r\n\r\n| parameter             | type    | description                             |\r\n| -----------           |-------  |---------------------------------------- |\r\n| `useUninstallSandbox` | `bool`  | true if you are using a APN certificate |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setUseUninstallSandbox(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n## In-App Purchase Validation (iOS)\r\n\r\nAppsFlyer provides two versions of the `validateAndSendInAppPurchase` method for iOS:\r\n\r\n- **V2 (Recommended)**: Uses structured data classes (`AFSDKPurchaseDetailsIOS`) for better type safety and cleaner code\r\n- **Legacy**: Uses individual string parameters (deprecated, maintained for backward compatibility)\r\n\r\n### validateAndSendInAppPurchase (V2 - Recommended) {#validateandsendinapppurchase-v2---recommended-1}\r\n**`void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> purchaseAdditionalDetails, MonoBehaviour gameObject)`**\r\n \r\nTo send and validate in app purchases you can call this method from the processPurchase method (V2).\r\n\r\n> **Note on iOS Error Handling:** The `onValidateAndLogFailure` callback is only triggered for actual errors (network errors, invalid parameters, etc.). Validation failures (e.g., invalid receipt) are returned through the `onValidateAndLogComplete` callback in the response dictionary. Always check the response to determine if validation was successful.\r\n\r\n| parameter                    | type                           | description  |\r\n| -----------                  |-------------------             | ------------------------------------------|\r\n| `details`                    | `AFSDKPurchaseDetailsIOS`      | Instance of AFSDKPurchaseDetailsIOS class |\r\n| `purchaseAdditionalDetails`  | `Dictionary<string, string>`   | Additional parameters to be sent with the purchase |\r\n| `gameObject`                 | `MonoBehaviour`                | Game object for the callbacks to be sent |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AFSDKPurchaseDetailsIOS details = AFSDKPurchaseDetailsIOS.Init(\"productId\", \"price\", \"currency\",\r\n        \"transactionId\");\r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        details, \r\n        null, \r\n        this);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### validateAndSendInAppPurchase (Legacy - Deprecated) {#validateandsendinapppurchase-legacy-1}\r\n**`void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`**\r\n \r\n**⚠️ Deprecated:** This legacy API is deprecated. Use the V2 version with `AFSDKPurchaseDetailsIOS` instead. This method is maintained for backward compatibility only.\r\nTo send and validate in app purchases you can call this method from the processPurchase method.\r\n\r\n| parameter              | type                           | description  |\r\n| -----------            |-------------------             | --------------|\r\n| `productIdentifier`    | `string`                       | The product identifier |\r\n| `price`                | `string`                       | The product price |\r\n| `currency`             | `string`                       | The product currency |\r\n| `transactionId`        | `string`                       | The purchase transaction ID |\r\n| `additionalParameters` | `Dictionary<string, string>`   | Additional parameters to be sent with the purchase |\r\n| `gameObject`           | `MonoBehaviour`                | Game object for the callbacks |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        \"productIdentifier\", \r\n        \"price\", \r\n        \"currency\", \r\n        \"transactionId\", \r\n        null, \r\n        this);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n\r\n### registerUninstall\r\n**` void registerUninstall(byte[] deviceToken)`**\r\n \r\n\r\nRegister uninstall - you should register for remote notification and provide AppsFlyer the push device token.\r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `deviceToken` | `byte[]`   | APN token    |\r\n\r\n*Example:*\r\n\r\n```c#\r\n    private bool tokenSent;\r\n\r\n    void Update()\r\n    {\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        if (!tokenSent)\r\n        {\r\n            byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;\r\n            if (token != null)\r\n            {\r\n                AppsFlyer.registerUninstall(token);\r\n                tokenSent = true;\r\n            }\r\n        }\r\n#endif\r\n    }\r\n\r\n```\r\n\r\n---\r\n\r\n### handleOpenUrl \r\n**`void handleOpenUrl(string url, string sourceApplication, string annotation)`**\r\n\r\n\r\n    In case you want to track deep linking manually call handleOpenUrl.\r\n    The continueUserActivity and onOpenURL are implemented in the AppsFlyerAppController.mm class, so \r\n    only use this method if the other methods do not cover your apps deeplinking needs.\r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `url`         | `string`   |      The URL to be passed to your AppDelegate        |\r\n| `sourceApplication` | `string`   |    The sourceApplication to be passed to your AppDelegate    |\r\n| `annotation`  | `string`   |       The annotation to be passed to your app delegate       |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    AppsFlyer.handleOpenUrl(string url, string sourceApplication, string annotation);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### waitForATTUserAuthorizationWithTimeoutInterval \r\n**` void waitForATTUserAuthorizationWithTimeoutInterval(int timeoutInterval)`**\r\n\r\nSee [here](https://support.appsflyer.com/hc/en-us/articles/207032066-iOS-SDK-V6-X-integration-guide-for-developers#integration-33-configuring-app-tracking-transparency-att-support) for more info. \r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `timeoutInterval`         | `int`   |      Time to wait for idfa        |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(60);\r\n#endif\r\n```\r\n---\r\n\r\n### disableSKAdNetwork \r\n**` bools disableSKAdNetwork(bool isDisabled)`**\r\n\r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `isDisabled`         | `bool`   |      True to disable SKAdNetwork     |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    AppsFlyer.disableSKAdNetwork(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### setLanguage\r\n**` setCurrentDeviceLanguage(string language)`**\r\n\r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `language`         | `String`   |    The language to set   |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    AppsFlyer.setCurrentDeviceLanguage(\"english\");\r\n#endif\r\n```\r\n\r\n---\r\n\r\n### disableIDFVCollection\r\n**` disableIDFVCollection(bool isDisabled)`**\r\n\r\n\r\n| parameter     | type       | description  |\r\n| -----------   |----------  |--------------|\r\n| `isDisabled`         | `bool`   |    True to disable IDFV collection   |\r\n\r\n*Example:*\r\n\r\n```c#\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n    AppsFlyer.disableIDFVCollection(true);\r\n#endif\r\n```\r\n\r\n---\r\n\r\n## IAppsFlyerConversionData\r\n  \r\n### onConversionDataSuccess \r\n**`public void onConversionDataSuccess(string conversionData)`**\r\n \r\n ConversionData contains information about install.<br> Organic/non-organic, etc. See [here](https://support.appsflyer.com/hc/en-us/articles/360000726098-Conversion-Data-Scenarios#Introduction) for more info.\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `conversionData`     | `string`  | JSON string of the returned conversion data |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n   public void onConversionDataSuccess(string conversionData)\r\n    {\r\n        AppsFlyer.AFLog(\"onConversionDataSuccess\", conversionData);\r\n        Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);\r\n        // add deferred deeplink logic here\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onConversionDataFail\r\n**`public void onConversionDataFail(string error)`**\r\n \r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `error`     | `string`  | A string describing the error |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n    public void onConversionDataFail(string error)\r\n    {\r\n        AppsFlyer.AFLog(\"onConversionDataFail\", error);\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onAppOpenAttribution\r\n**`public void onAppOpenAttribution(string attributionData)`**\r\n \r\nattributionData contains information about OneLink, deeplink.\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `attributionData`     | `string`  | JSON string of the returned deeplink data |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n    public void onAppOpenAttribution(string attributionData)\r\n    {\r\n        AppsFlyer.AFLog(\"onAppOpenAttribution\", attributionData);\r\n        Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);\r\n        // add direct deeplink logic here\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onAppOpenAttributionFailure \r\n**`public void onAppOpenAttributionFailure(string error)`**\r\n    \r\nAny errors that occurred during the attribution request.\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `error`     | `string`  | string describing the error |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n  public void onAppOpenAttributionFailure(string error)\r\n    {\r\n        AppsFlyer.AFLog(\"onAppOpenAttributionFailure\", error);\r\n    }\r\n```\r\n\r\n---\r\n\r\n## IAppsFlyerUserInvite\r\n  \r\n### onInviteLinkGenerated \r\n**`public void onInviteLinkGenerated(string link)`**\r\n \r\nThe success callback for generating OneLink URLs. \r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `link`     | `string`  | generated link |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n   public void onInviteLinkGenerated(string link)\r\n    {\r\n\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onInviteLinkGeneratedFailure \r\n**`public void onInviteLinkGeneratedFailure(string error)`**\r\n \r\n The error callback for generating OneLink URLs\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `error`     | `string`  | A string describing the error |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n    public void onInviteLinkGeneratedFailure(string error)\r\n    {\r\n        AppsFlyer.AFLog(\"onInviteLinkGeneratedFailure\", error);\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onOpenStoreLinkGenerated\r\n**`public void onOpenStoreLinkGenerated(string link)`**\r\n \r\n       \r\n (ios only) iOS allows you to utilize the StoreKit component to open\r\n the App Store while remaining in the context of your app.<br>\r\n More details at [here](https://support.appsflyer.com/hc/en-us/articles/115004481946-Cross-Promotion-Tracking#tracking-cross-promotion-impressions)\r\n     \r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `attributionData`     | `string`  | JSON string of the returned deeplink data |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n    public void onOpenStoreLinkGenerated(string link)\r\n    {\r\n\r\n    }\r\n```\r\n\r\n---\r\n\r\n##  IAppsFlyerValidateReceipt\r\n  \r\n### didFinishValidateReceipt \r\n**`public void didFinishValidateReceipt(string result)`**\r\n \r\nThe success callback for validateAndSendInAppPurchase API.<br>\r\nFor Android : the callback will return \"Validate success\".<br>\r\nFor iOS : the callback will return a JSON string from apples verifyReceipt API. <br>\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `result`     | `string`  | validate result |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n   public void didFinishValidateReceipt(string link)\r\n    {\r\n\r\n    }\r\n```\r\n\r\n---\r\n\r\n##  IAppsFlyerValidateAndLog\r\n  \r\n### onValidateAndLogComplete \r\n**`public void onValidateAndLogComplete(string result)`**\r\n \r\nThe success callback for validateAndSendInAppPurchase API.<br>\r\nThe callback will return a JSON string which can be converted to dictionary. <br>\r\n> **Note for iOS:** On iOS, this callback is invoked for all successful API calls, including cases where validation fails (e.g., invalid receipt). Always check the response dictionary to determine the actual validation result. Only network errors and invalid parameters trigger `onValidateAndLogFailure`.\r\n\r\n| parameter   | type      | description        |\r\n| ----------  |---------- |--------------------|\r\n| `result`    | `string`  | validate result     |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n   public void onValidateAndLogComplete(string result)\r\n    {\r\n        AppsFlyer.AFLog(\"onValidateAndLogComplete\", result);\r\n        Dictionary<string, object> validateAndLogDataDictionary = AppsFlyer.CallbackStringToDictionary(result);\r\n    }\r\n```\r\n\r\n---\r\n\r\n### onValidateAndLogFailure \r\n**`public void onValidateAndLogFailure(string error)`**\r\n \r\n The error callback for validating receipts.<br>\r\n The callback will return a JSON string which can be converted to dictionary. <br>\r\n> **Note for iOS:** On iOS, this callback is only triggered for actual errors (network errors, invalid parameters, etc.). Validation failures (e.g., invalid receipt) are returned through `onValidateAndLogComplete` in the response dictionary.\r\n\r\n| parameter   | type      | description                   |\r\n| ----------  |---------- |----------------------------   |\r\n| `error`     | `string`  | A string describing the error |\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n    public void onValidateAndLogFailure(string error)\r\n    {\r\n         AppsFlyer.AFLog(\"onValidateAndLogFailure\", error); \r\n    }\r\n```\r\n\r\n---\r\n\r\n## Events\r\n    \r\n### onRequestResponse\r\n**`public static event EventHandler OnRequestResponse`**\r\n \r\n The callback for Sessions.<br>\r\n\r\n| statusCode      | errorDescription | \r\n| ----------- | ----------- | \r\n| 200      | null       | \r\n| 10   | \"Event timeout. Check 'minTimeBetweenSessions' param\"        | \r\n| 11   | \"Skipping event because 'isStopTracking' enabled\"        | \r\n| 40   | Network error: Error description comes from Android        | \r\n| 41   | \"No dev key\"        | \r\n| 50   | \"Status code failure\" + actual response code from the server        | \r\n\r\n*Example:*\r\n\r\n```c#\r\n    AppsFlyer.OnRequestResponse += (sender, args) =>\r\n    {\r\n        var af_args = args as AppsFlyerRequestEventArgs;\r\n        AppsFlyer.AFLog(\"AppsFlyerOnRequestResponse\", \"status code\" + af_args.statusCode);\r\n    };\r\n```\r\n\r\n---\r\n\r\n### onInAppResponse\r\n**`public static event EventHandler OnInAppResponse`**\r\n \r\n The callback for In-App Events.<br>\r\n\r\n| statusCode      | errorDescription | \r\n| ----------- | ----------- | \r\n| 200      | null       | \r\n| 10   | \"Event timeout. Check 'minTimeBetweenSessions' param\"        | \r\n| 11   | \"Skipping event because 'isStopTracking' enabled\"        | \r\n| 40   | Network error: Error description comes from Android        | \r\n| 41   | \"No dev key\"        | \r\n| 50   | \"Status code failure\" + actual response code from the server        | \r\n\r\n*Example:*\r\n\r\n```c#\r\n\r\n    AppsFlyer.OnInAppResponse += (sender, args) =>\r\n    {\r\n        var af_args = args as AppsFlyerRequestEventArgs;\r\n        AppsFlyer.AFLog(\"OnRequestResponse\", \"status code\" + af_args.statusCode);\r\n    }; \r\n\r\n```\r\n\r\n---\r\n\r\n### onDeepLinkReceived \r\n**`public static event EventHandler OnDeepLinkReceived`**\r\n \r\n The callback for Unified Deeplink API.<br>\r\n\r\n\r\n*Example:*\r\n\r\n```c#\r\n\r\n    // First call init with devKey, appId and gameObject\r\n    AppsFlyer.initSDK(devKey, appID, this);\r\n\r\n\r\n    AppsFlyer.OnDeepLinkReceived += (sender, args) =>\r\n    {\r\n        var deepLinkEventArgs = args as DeepLinkEventsArgs;\r\n\r\n        // DEEPLINK LOGIC HERE\r\n    }; \r\n\r\n```\r\n\r\n---\r\n"
  },
  {
    "path": "docs/BasicIntegration.md",
    "content": "---\ntitle: Integration\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 1\nhidden: false\n---\n\nYou can initialize the plugin by using the AppsFlyerObject prefab or manually.\n\n- [Using the AppsFlyerObject.prefab](#using-the-appsflyerobjectprefab)\n- [Manual integration](#manual-integration)\n- [Collect IDFA with ATTrackingManager](#collect-idfa-with-attrackingmanager)\n- [Send consent for DMA compliance](#send-consent-for-dma-compliance)\n- [Sending SKAN postback to Appsflyer](#sending-skan-postback-to-appsflyer)\n- [MacOS initialization](#macos-initialization)\n- [Request Listeners (Optional)](#request-listeners-optional)\n\n## Using the AppsFlyerObject.prefab\n\n1. Go to Assets > AppsFlyer and drag AppsFlyerObject.prefab to your scene.\n<img src=\"assets/unity_add_object.png\" width=\"650\">\n<br/>\n2. Update the following fields:\n\n| Setting  | Description   |\n| -------- | ------------- |\n| **Dev Key**   |  AppsFlyer's [Dev Key](https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers#integration-31-retrieving-your-dev-key), which is accessible from the AppsFlyer dashboard. |\n| **App ID**      | Your iTunes Application ID. (If your app is not for iOS the leave field empty)  |\n| **Get Conversion Data**    | Set this to true if your app is using AppsFlyer for deep linking.  |\n| **Is Debug**    | Set this to true to view the debug logs. (for development only!)  |\n\n3. Update the code in Assets > AppsFlyer > AppsFlyerObjectScript.cs with other available [API](/docs/api).\n\n## Manual integration\n\nCreate a game object and add the following init code:\n\n```c#\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour\n{\n  void Start()\n  {\n    AppsFlyer.initSDK(\"devkey\", \"appID\");\n    AppsFlyer.startSDK();\n  }\n}\n```\n\n> **Note:** \n> - Make sure not to call destroy on the game object. \n> - Use [`DontDestroyOnLoad`](https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html) to keep the object when loading a new scene.\n\n---\n\n## Set customer user ID\n\nSet your own unique customer user ID (CUID) and cross-reference it with the unique AppsFlyer ID.\n\n- Appear in AppsFlyer raw data CSV reports.\n- Can be used in postback APIs to cross-reference with internal IDs.  \n  To set the CUID, use:\n\n```c#\nAppsFlyer.setCustomerUserId(\"someId\");\n```\n\n**Good practice!** Set the CUID early in the app flow—it is only associated with events reported after its setup.\n\n- Recorded events will be associated with the CUID.\n- Related data will appear in the raw data reports for installs and events..\n\n### Associate the CUID with the install event\n\nIf it’s important for you to associate the install event with the CUID, call `setCustomerUserId` before calling `startSDK`.\n\n## Collect IDFA with ATTrackingManager\n\n1. Add the `AppTrackingTransparency` framework to your xcode project. \n2. In the `Info.plist`:\n    1. Add an entry to the list: Press +  next to `Information Property List`.\n    2. Scroll down and select `Privacy - Tracking Usage Description`.\n    3. Add as the value the wording you want to present to the user when asking for permission to collect the IDFA.\n3. Call the `waitForATTUserAuthorizationWithTimeoutInterval` api before `startSDK()`\n    \n    ```c#\n    #if UNITY_IOS && !UNITY_EDITOR\n    AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(60);\n    #endif\n    ```\n        \n4. Request the tracking authorization where you wish to display the prompt: <br/>\n    You can use the following [package](https://github.com/Unity-Technologies/com.unity.ads.ios-support) or any other package that allows you to request the tracking authorization. \n    ```c#\n\n    using Unity.Advertisement.IosSupport;\n\n    /*  ... */\n  \n    if (ATTrackingStatusBinding.GetAuthorizationTrackingStatus() \n         == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED)\n        {\n            ATTrackingStatusBinding.RequestAuthorizationTracking();\n        }\n     /*  ... */\n  \n### Customizing the ATT consent dialog\n\nThe ATT consent dialog can be customized by modifying your Xcode project's `info.plist`:\n\nFor detailed instructions, see [Apple's documentation](https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription).\n  \n---\n\n## Send consent for DMA compliance\n\nUnity SDK plugin offers two alternative methods for gathering consent data:\n\nThrough a Consent Management Platform (CMP): If the app uses a CMP that complies with the Transparency and Consent Framework (TCF) v2.2 protocol, the Unity SDK can automatically retrieve the consent details.\n\nOR\n\nThrough a dedicated Unity SDK API: Developers can pass Google's required consent data directly to the Unity SDK using a specific API designed for this purpose.\n\n### Use CMP to collect consent data\n\n1. Initialize the SDK.\n2. Call enableTCFDataCollection(true) api before startSDK() to instruct the SDK to collect the TCF data from the device.\n3. Use the CMP to decide if you need the consent dialog in the current session to acquire the consent data. If you need the consent dialog move to step 4; otherwise move to step 5.\n4. Get confirmation from the CMP that the user has made their consent decision and the data is available.\n5. Call start().\n    \n    ```c#\n        AppsFlyer.initSDK(devKey, appID, this);\n\n        AppsFlyer.enableTCFDataCollection(true);\n        \n        //YOUR_CMP_FLOW()\n        // if already has consent ready - you can start\n            AppsFlyer.startSDK();\n            \n        //else Waiting for CMP completion and data ready and then start\n        \n            AppsFlyer.startSDK();\n    ```\n\n### Manually collect consent data\n\n1. Initialize the SDK.\n2. Determine whether the GDPR applies or not to the user.\n\n### When GDPR applies to the user\n1. Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.\n    i.  If there is no consent data stored, show the consent dialog to capture the user consent decision.\n    ii. If there is consent data stored continue to the next step.\n    \n2. To transfer the consent data to the SDK create an AppsFlyerConsent object with the following parameters:\n    - hasConsentForDataUsage - Indicates whether the user has consented to use their data for advertising purposes.\n    - hasConsentForAdsPersonalization - Indicates whether the user has consented to use their data for personalized advertising.\n3. Call setConsentData()with the AppsFlyerConsent object.\n5. Call start().\n    \n    ```c#\n            \n        // If the user is subject to GDPR - collect the consent data\n        // or retrieve it from the storage\n        ...\n        // Set the consent data to the SDK:\n        AppsFlyerConsent consent = AppsFlyerConsent.ForGDPRUser(true, true);\n        AppsFlyer.setConsentData(consent);\n            \n        AppsFlyer.startSDK();\n    ```\n\n### When GDPR does not apply to the user\n1. Create an AppsFlyerConsent object using the ForNonGDPRUser() initializer. This initializer doesn’t accept any parameters.\n2. Pass the empty AppsFlyerConsent object to setConsentData().\n2. Call start().\n    \n    ```c#\n        // If the user is not subject to GDPR:\n        AppsFlyerConsent consent = AppsFlyerConsent.ForNonGDPRUser();\n        AppsFlyer.setConsentData(consent);\n            \n        AppsFlyer.startSDK();\n    ```\n\n ## Verify consent data is sent\n To test whether your SDK sends DMA consent data with each event, perform the following steps:\n \n 1. Enable the SDK debug mode.\n 2. Search for consent_data in the log of the outgoing request.\n \n for more information visit [iOS](https://dev.appsflyer.com/hc/docs/ios-send-consent-for-dma-compliance)  \n                            [Android](https://dev.appsflyer.com/hc/docs/android-send-consent-for-dma-compliance)  \n---\n\n## Sending SKAN postback to Appsflyer\n  To register the AppsFlyer endpoint, you need to add the `NSAdvertisingAttributionReportEndpoint` key to your info.plist and set the value to `https://appsflyer-skadnetwork.com/`. \nMore info on how to update the info.plist can be found [here](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/docs/Troubleshooting.md#updating-the-infoplist). \n\n--- \n\n## MacOS initialization\n1. Use the prefab `AppsFlyerObject`\n2. Add your MacOS app id\n3. Build for the platform `PC, Mac & Linux Standelone` and choose `MacOS` as the target platform.\n  \n---\n## Request Listeners (Optional)\n    \n1. Attach the 'AppsFlyer.cs' script to the game object with the AppsFlyer init code. (AppsFlyerObject, ect)\n2. Add the following code **before** startSDK()\n\nSessions response example:\n\n```c#\n    void Start()\n    {\n        AppsFlyer.OnRequestResponse += AppsFlyerOnRequestResponse;\n        \n        AppsFlyer.initSDK(devKey, appID, this);\n        AppsFlyer.startSDK();\n    }\n\n    void AppsFlyerOnRequestResponse(object sender, EventArgs e)\n    {\n        var args = e as AppsFlyerRequestEventArgs;\n        AppsFlyer.AFLog(\"AppsFlyerOnRequestResponse\", \" status code \" + args.statusCode);\n    }\n```\n\nIn-App response example:\n\n```c#\n    void Start()\n    {\n        AppsFlyer.OnInAppResponse += (sender, args) =>\n        {\n            var af_args = args as AppsFlyerRequestEventArgs;\n            AppsFlyer.AFLog(\"AppsFlyerOnRequestResponse\", \" status code \" + af_args.statusCode);\n        };\n        \n        AppsFlyer.initSDK(devKey, appID, this);\n        AppsFlyer.startSDK();\n    }\n\n\n```\n\n| statusCode      | errorDescription | \n| ----------- | ----------- | \n| 200      | null       | \n| 10   | \"Event timeout. Check 'minTimeBetweenSessions' param\"        | \n| 11   | \"Skipping event because 'isStopTracking' enabled\"        | \n| 40   | Network error: Error description comes from Android        | \n| 41   | \"No dev key\"        | \n| 50   | \"Status code failure\" + actual response code from the server        | \n\n---\n"
  },
  {
    "path": "docs/DMAConsent.md",
    "content": "---\ntitle: Sending Consent Data for DMA Compliance\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 4\nhidden: false\n---\n\n# Send consent for DMA compliance (Unity)\n\nFor a general introduction to DMA consent data, see the [DMA consent overview](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance) in the AppsFlyer docs. The SDK offers two alternative methods for gathering consent data:\n\n- **Through a Consent Management Platform (CMP):** If your app uses a CMP that complies with the IAB **Transparency and Consent Framework (TCF) v2.2/2.3**, the SDK can automatically retrieve consent details.\n\n**OR**\n\n- **Through a dedicated SDK API:** Provide Google’s required consent data directly to the SDK using the **Unity** consent APIs.\n\n> **Note**  \n> Use **only one** method per specific event. If both are supplied for the same event, AppsFlyer prioritizes the manual consent data sent via the dedicated API.\n\n---\n\n## Use CMP to collect consent data\n\nA CMP compatible with **TCF v2.2/2.3** persists the consent strings on-device (NSUserDefaults on iOS / SharedPreferences on Android). To enable the Unity SDK to access this data and include it with every event, follow these steps:\n\n1. **Initialize** the SDK (in your Unity scene startup code).  \n2. **Before** starting the SDK, call `AppsFlyer.enableTCFDataCollection(true)` to instruct the SDK to collect TCF data from the device.  \n3. Use your CMP to decide if the consent dialog is needed in the current session.  \n4. If needed, **show the consent dialog** to capture the user’s decision; otherwise skip to step 6.  \n5. After the CMP confirms the user made a decision and the TCF data is stored, proceed.  \n6. Call `AppsFlyer.startSDK()`.\n\n### Unity (C#) example\n\n```csharp\nusing AppsFlyerSDK;\nusing UnityEngine;\n\npublic class DMAConsentCmpFlow : MonoBehaviour\n{\n    [SerializeField] string devKey = \"AF_DEV_KEY\";\n    [SerializeField] string appId  = \"com.example.app\"; // empty on Android\n\n    void Start()\n    {\n        AppsFlyer.initSDK(devKey, appId);\n        AppsFlyer.enableTCFDataCollection(true); // collect TCF strings from device\n\n        // Pseudocode for your CMP flow:\n        if (CmpManager.HasConsentReady())\n        {\n            AppsFlyer.startSDK();\n        }\n        else\n        {\n            CmpManager.ShowDialog(onUserDecided: () =>\n            {\n                // CMP indicates consent data now stored in device prefs\n                AppsFlyer.startSDK();\n            });\n        }\n    }\n}\n```\n\n---\n\n## Manually collect consent data\n\nIf your app **does not** use a TCF v2.2/2.3-compatible CMP, provide the consent data directly to the SDK via `AppsFlyer.setConsentData(AppsFlyerConsent)`.\n\n1. **Initialize** the SDK in your startup flow.  \n2. Determine whether **GDPR applies** to the user.  \n3. Check whether consent data is **already stored** for this session.  \n   - If not stored, **show your own consent dialog** and collect the user’s choices.  \n   - If stored, continue.  \n4. Create an `AppsFlyerConsent` instance with the following parameters, then call `AppsFlyer.setConsentData(consent)`:\n   - `isUserSubjectToGDPR` – whether GDPR applies to this user.  \n   - `hasConsentForDataUsage` – consent to use data for advertising/measurement.  \n   - `hasConsentForAdsPersonalization` – consent for personalized ads.  \n   - `hasConsentForAdStorage` – consent to store/access information on the device.  \n5. If GDPR **does not apply**, set `isUserSubjectToGDPR = false` and **the rest to `null`**.  \n6. Call `AppsFlyer.startSDK()`.\n\n### Unity (C#) examples\n\n**GDPR applies (example values):**\n```csharp\n// Build from your dialog results\nvar consent = new AppsFlyerConsent(\n    isUserSubjectToGDPR:            true,\n    hasConsentForDataUsage:         true,\n    hasConsentForAdsPersonalization:true,\n    hasConsentForAdStorage:         false\n);\n\nAppsFlyer.setConsentData(consent);\nAppsFlyer.startSDK();\n```\n\n**GDPR does NOT apply:**\n```csharp\nvar nonGdpr = new AppsFlyerConsent(\n    isUserSubjectToGDPR:            false,\n    hasConsentForDataUsage:         null,\n    hasConsentForAdsPersonalization:null,\n    hasConsentForAdStorage:         null\n);\n\nAppsFlyer.setConsentData(nonGdpr);\nAppsFlyer.startSDK();\n```\n\n> **Note**  \n> The SDK registers only the parameters you explicitly pass via the `AppsFlyerConsent` object. (Unset parameters remain unknown.)\n\n---\n\n## Verify consent data is sent\n\nTo confirm the SDK sends DMA consent data with each event:\n\n1. **Enable debug mode** in the Unity Plugin (development only).  \n2. Inspect the device logs for the outgoing request and look for a `consent_data` section.  \n   - **CMP flow** includes a `tcf` block (e.g., `gdpr_applies`, `tcstring`, `cmp_sdk_id`, `policy_version`).  \n   - **Manual flow** includes a `manual` block (e.g., `gdpr_applies`, `ad_user_data_enabled`, `ad_personalization_enabled`).  \n\nExample patterns from Android/iOS logs (your Unity build will emit analogous payloads per platform):\n\n- CMP flow: `...\"consent_data\":{\"tcf\":{\"policy_version\":4,\"cmp_sdk_id\":...,\"gdpr_applies\":1,\"tcstring\":\"...\"}}...`  \n- Manual flow: `...\"consent_data\":{\"manual\":{\"gdpr_applies\":true,\"ad_user_data_enabled\":true,\"ad_personalization_enabled\":true}}...`\n\n---\n\n## Quick API reference (Unity)\n\n- **Collect TCF strings automatically:**  \n  `AppsFlyer.enableTCFDataCollection(true|false)` — call **before** `startSDK()`.\n\n- **Send manual consent:**  \n  `AppsFlyer.setConsentData(AppsFlyerConsent consent)` with:  \n  `AppsFlyerConsent(bool? isUserSubjectToGDPR, bool? hasConsentForDataUsage, bool? hasConsentForAdsPersonalization, bool? hasConsentForAdStorage)` (use `null` where unknown/not applicable).\n\n---\n\n### Notes & best practices\n\n- Set consent **before** `startSDK()` so the first session includes the correct signals.  \n- If the user changes their choice later, rebuild `AppsFlyerConsent` with the new values and call `setConsentData` again.\n"
  },
  {
    "path": "docs/DeepLinkIntegrate.md",
    "content": "---\ntitle: Deep Linking - Installation\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 6\nhidden: false\n---\n\n# Getting started\n\n    \n![alt text](https://massets.appsflyer.com/wp-content/uploads/2018/03/21101417/app-installed-Recovered.png \"\")\n\n\n## Deep Linking Types:\n1. **Deferred Deep Linking** - Serving personalized content to new or former users, directly after the installation. \n2. **Direct Deep Linking** - Directly serving personalized content to existing users, which already have the mobile app installed.\n\n** Unified deep linking (UDL) ** - an  API which enables you to send new and existing users to a specific in-app activity as soon as the app is opened.\n\nFor more info please check out the [OneLink™ Deep Linking Guide](https://support.appsflyer.com/hc/en-us/articles/208874366-OneLink-Deep-Linking-Guide#Intro) and [developer guide](https://dev.appsflyer.com/hc/docs/getting-started-1).\n\n---\n\n#  Android Deeplink Setup\n    \n## App Links\nFor more on App Links check out the guide [here](https://dev.appsflyer.com/hc/docs/initial-setup-for-deep-linking-and-deferred-deep-linking#procedures-for-android-app-links).\n\n##  URI scheme in Android\n\nFull setup guide for URI scheme in Android can be found [here](https://dev.appsflyer.com/hc/docs/initial-setup-for-deep-linking-and-deferred-deep-linking#procedures-for-uri-scheme).\n\n#  iOS Deeplink Setup\n\n## Universal Links \n\nEssentially, the Universal Links method links between an iOS mobile app and an associate website/domain, such as AppsFlyer’s OneLink domain (xxx.onelink.me). For more on Universal Links check out the guide [here](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-ios-universal-links).\n\n## URI scheme in iOS\n\nFull setup guide for URI scheme in iOS can be found [here](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-uri-scheme).\n"
  },
  {
    "path": "docs/InAppEvents.md",
    "content": "---\ntitle: In-App Events\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 3\nhidden: false\n---\n\n- [Overview](#overview)\n- [Send Event](#send-event)\n- [In-app purchase validation (V2)](#in-app-purchase-validation-v2)\n- [In-app purchase validation (legacy)](#in-app-purchase-validation)\n\n## Overview\n\nIn-App Events provide insight on what is happening in your app. It is recommended to take the time and define the events you want to measure to allow you to measure *ROI* (Return on Investment) and *LTV* (Lifetime Value).\n\nRecording in-app events is performed by calling `sendEvent` with event name and value parameters. See In-App Events [documentation](https://support.appsflyer.com/hc/en-us/articles/115005544169-Rich-in-app-events-for-Android-and-iOS#introduction-predefined-and-custom-events) for more details.\n\nFind more info about recording events [here](https://dev.appsflyer.com/hc/docs/in-app-events-sdk).\n\n## Send Event\n\n`void sendEvent(string eventName, Dictionary<string, string> eventValues)`\n\n\n| parameter      | type                         | description                                   |\n| -----------    |----------------------------- |------------------------------------------     |\n| `eventName`    | `string`                     | The name of the event                         |\n| `eventValues`  | `Dictionary<string, string>` | The event values that are sent with the event |\n\n\n*Example:*\n\n```c#\nDictionary<string, string> eventValues = new Dictionary<string, string>();\neventValues.Add(AFInAppEvents.CURRENCY, \"USD\");\neventValues.Add(AFInAppEvents.REVENUE, \"0.99\");\neventValues.Add(\"af_quantity\", \"1\");\nAppsFlyer.sendEvent(AFInAppEvents.PURCHASE, eventValues);\n```\n***\n\n## Logging revenue\n\n> 📘 Note\n>\n> For events with **revenue**, including in-app purchases, subscriptions, and ad revenue events, AppsFlyer customers with an ROI360 subscription should avoid using the `AFInAppEvents.REVENUE`(`af_revenue`) parameter in their in-app events. Doing so can result in duplicate revenue being reported. Instead, they should utilize the [purchase connector](https://dev.appsflyer.com/hc/docs/purchaseconnectorunity) and the [ad revenue SDK API](https://dev.appsflyer.com/hc/docs/ad-revenue-unity).\n\nYou can send revenue with any in-app event. Use the `AFInAppEvents.REVENUE` event parameter to include revenue in the in-app event. You can populate it with any numeric value, positive or negative.\n\nThe revenue value should not contain comma separators, currency signs, or text. A revenue event should be similar to 1234.56, for example.\n\nCurrency code requirements when sending revenue events\n\n- Default currency: USD\n- Use a [3-character ISO 4217 code](https://en.wikipedia.org/wiki/ISO_4217#Active_codes) (an example follows).\n- Set the currency code by calling the API:\n    \n\n    ```c#\n    AppsFlyer.setCurrencyCode(\"ZZZ\")\n    ```   \n\n**Example: In-app purchase event with revenue**\nThis purchase event is for 200.12 Euros. For the revenue to reflect in the dashboard use the following.\n\n```c#\nusing System.Collections.Generic;\n\nDictionary<string, string> purchaseEvent = new Dictionary<string, string> ();\npurchaseEvent.Add(AFInAppEvents.CURRENCY, \"EUR\");\npurchaseEvent.Add(AFInAppEvents.REVENUE, \"200.12\");\npurchaseEvent.Add(AFInAppEvents.QUANTITY, \"1\");\npurchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, \"category_a\",);\nAppsFlyer.sendEvent (\"af_purchase\", purchaseEvent);\n```\n\n> 📘 Note\n> Do not add currency symbols to the revenue value.\n\n### Logging negative revenue\nRecord negative revenue using a minus sign.\n- Revenue value is preceded by a minus sign.\n- The event name has a unique value, \"cancel_purchase\". This lets you identify negative revenue events in raw data reports and in the Dashboard.\n\n**Example: App user receives a refund or cancels a subscription**\n\n```c#\nusing System.Collections.Generic;\n\nDictionary<string, string> purchaseEvent = new Dictionary<string, string> ();\npurchaseEvent.Add(AFInAppEvents.CURRENCY, \"USD\");\npurchaseEvent.Add(AFInAppEvents.REVENUE, \"-200\");\npurchaseEvent.Add(AFInAppEvents.QUANTITY, \"1\");\npurchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, \"category_a\");\nAppsFlyer.sendEvent (\"cancel_purchase\", purchaseEvent);\n```\n\n## In-app purchase validation (V2)\n\nFor In-App Purchase Receipt Validation, follow the instructions according to your operating system.\n\n**Notes**\n- Calling validateReceipt automatically generates an `af_purchase` in-app event, so you don't need to send this event yourself.\n- The validate purchase response is triggered in the `AppsFlyerTrackerCallbacks.cs` class.\n- **iOS Error Handling:** On iOS, the `onValidateAndLogFailure` callback is only triggered for actual errors (network errors, invalid parameters, etc.). Validation failures (e.g., invalid receipt) are returned through the `onValidateAndLogComplete` callback in the response dictionary. Check the response to determine if validation was successful.\n\n```c#\n// for Android \n`void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`\n// for iOS \n`void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> extraEventValues, MonoBehaviour gameObject)`\n\n```\n\n```c#\nusing UnityEngine.Purchasing;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObject : MonoBehaviour, IAppsFlyerValidateAndLog\n{\n\n    public static string kProductIDConsumable = \"com.test.cons\";\n\n    void Start()\n    {\n        AppsFlyer.initSDK(\"devKey\", \"devKey\");\n        AppsFlyer.startSDK();\n    }\n\n    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n    {\n        string prodID = args.purchasedProduct.definition.id;\n        string price = args.purchasedProduct.metadata.localizedPrice.ToString();\n        string currency = args.purchasedProduct.metadata.isoCurrencyCode;\n\n        string receipt = args.purchasedProduct.receipt;\n        var recptToJSON = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize(product.receipt);\n        var receiptPayload = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize((string)recptToJSON[\"Payload\"]);\n        var transactionID = product.transactionID;\n\n        if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal))\n        {\n#if UNITY_IOS\n\n            if(isSandbox)\n            {\n                AppsFlyeriOS.setUseReceiptValidationSandbox(true);\n            }\n\n            AFSDKPurchaseDetailsIOS details = AFSDKPurchaseDetailsIOS.Init(prodID, price, currency, transactionID);\n\n            AppsFlyeriOS.validateAndSendInAppPurchase(details, null, this);\n#elif UNITY_ANDROID\n\n        AFPurchaseDetailsAndroid details = new AFPurchaseDetailsAndroid(AFPurchaseType.Subscription, \"token\", prodID, price, currency);\n\n        AppsFlyerAndroid.validateAndSendInAppPurchase(\n        details,\n        null, \n        this);\n#endif\n        }\n\n        return PurchaseProcessingResult.Complete;\n    }\n\n    public void onValidateAndLogComplete(string result)\n    {\n        AppsFlyer.AFLog(\"onValidateAndLogComplete\", result);\n        Dictionary<string, object> validateAndLogDataDictionary = AppsFlyer.CallbackStringToDictionary(result);\n        // On iOS: Check the response dictionary to determine if validation was successful\n        // Validation failures are returned here, not in onValidateAndLogFailure\n    }\n\n    public void onValidateAndLogFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onValidateAndLogFailure\", error);\n        Dictionary<string, object> validateAndLogErrorDictionary = AppsFlyer.CallbackStringToDictionary(error);\n        // On iOS: This is only called for actual errors (network errors, invalid parameters, etc.)\n        // Validation failures come through onValidateAndLogComplete instead\n    }\n\n}\n\n```\n\n## In-app purchase validation\n\n> ⚠️ **Deprecated:** This legacy API is deprecated. Use the [V2 version](#in-app-purchase-validation-v2) with structured data classes (`AFPurchaseDetailsAndroid`/`AFSDKPurchaseDetailsIOS`) instead. The legacy methods are maintained for backward compatibility only.\n\nFor In-App Purchase Receipt Validation, follow the instructions according to your operating system.\n\n**Notes**\nCalling validateReceipt automatically generates an `af_purchase` in-app event, so you don't need to send this event yourself.\nThe validate purchase response is triggered in the `AppsFlyerTrackerCallbacks.cs` class.\n\n`void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string tranactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`\n\n```c#\n//To get the callbacks\n//AppsFlyer.createValidateInAppListener (\"AppsFlyerTrackerCallbacks\", \"onInAppBillingSuccess\", \"onInAppBillingFailure\");\nAppsFlyer.validateReceipt(string publicKey, string purchaseData, string signature, string price, string currency, Dictionary additionalParametes);\n```\n\n```c#\nusing UnityEngine.Purchasing;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObject : MonoBehaviour, IStoreListener, IAppsFlyerValidateReceipt\n{\n\n    public static string kProductIDConsumable = \"com.test.cons\";\n\n    void Start()\n    {\n        AppsFlyer.initSDK(\"devKey\", \"devKey\");\n        AppsFlyer.startSDK();\n    }\n\n    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n    {\n        string prodID = args.purchasedProduct.definition.id;\n        string price = args.purchasedProduct.metadata.localizedPrice.ToString();\n        string currency = args.purchasedProduct.metadata.isoCurrencyCode;\n\n        string receipt = args.purchasedProduct.receipt;\n        var recptToJSON = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize(product.receipt);\n        var receiptPayload = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize((string)recptToJSON[\"Payload\"]);\n        var transactionID = product.transactionID;\n\n        if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal))\n        {\n#if UNITY_IOS\n\n            if(isSandbox)\n            {\n                AppsFlyeriOS.setUseReceiptValidationSandbox(true);\n            }\n\n            AppsFlyeriOS.validateAndSendInAppPurchase(prodID, price, currency, transactionID, null, this);\n#elif UNITY_ANDROID\n        var purchaseData = (string)receiptPayload[\"json\"];\n        var signature = (string)receiptPayload[\"signature\"];\n        AppsFlyerAndroid.validateAndSendInAppPurchase(\n        \"<google_public_key>\", \n        signature, \n        purchaseData, \n        price, \n        currency, \n        null, \n        this);\n#endif\n        }\n\n        return PurchaseProcessingResult.Complete;\n    }\n\n    public void didFinishValidateReceipt(string result)\n    {\n        AppsFlyer.AFLog(\"didFinishValidateReceipt\", result);\n    }\n\n    public void didFinishValidateReceiptWithError(string error)\n    {\n        AppsFlyer.AFLog(\"didFinishValidateReceiptWithError\", error);\n    }\n\n}\n\n```\n\n\n"
  },
  {
    "path": "docs/Installation.md",
    "content": "---\ntitle: Installation\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 0\nhnameden: false\n---\n\n# Adding appsflyer-unity-plugin to your project\n\n## Adding the SDK to your project\n\nIn order to add the plugin to your project, you can either add the *unitypackage* **or** use *Unity Package Manager*. \n- [Installation adding the unitypackage](#using-unitypackage)\n- [Installation using Unity Package Manager](#using-unity-package-manager)\n\n**Note:**  The plugin is built with [The External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver) (EDM4U) (formerly Play Services Resolver / Jar Resolver)\n* The External Dependency Manager for Unity is distributed with the `appsflyer-unity-plugin` by default.\n* This will ease the integration process, by resolving dependency conflicts between your plugin and other plugins in your project.\n* Adding the `appsflyer-unity-plugin.v*.unitypackage` will automatically import all the assets required for both the AppsFlyer SDK and the External Dependency Manager for Unity.\n\n## Using unitypackage\n1. Clone / download the [plugin repository](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin).\n2. [Import](https://docs.unity3d.com/Manual/AssetPackages.html) the `appsflyer-unity-plugin-*.unitypackage` or `appsflyer-unity-plugin-strict-mode.*.unitypackage` file from the `strict-mode-sdk` folder for the Strict version of the plugin, into your Unity project.\n3. Go to Assets >> Import Package >> Custom Package.\n4. Select the `appsflyer-unity-plugin-*.unitypackage` file or the `appsflyer-unity-plugin-strict-mode.*.unitypackage` file from the `strict-mode-sdk` folder for the Strict version of the plugin.\n\n**Note:** If you do not wish to include [The External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver), refer to the steps of this [installation](#installation-without-unity-jar-resolver).\n\n## Using Unity Package Manager\n\n1. Follow Google's [guide](https://developers.google.com/unity/instructions) in order to integrate UPM (Unity Package Manager).\n**Note:** If you do not wish to include [The External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver), refer to steps 2 & 3 [here](#installation-without-unity-jar-resolver).\n\n\n4. Add appsflyer-unity-plugin in the dependency :\nAdd this line for the latest version of the regular mode\n```\n \"appsflyer-unity-plugin\": \"https://github.com/AppsFlyerSDK/appsflyer-unity-plugin.git#upm\"\n```\n Or this line for latest version of the Strict mode :\n```\n \"appsflyer-unity-plugin\": \"https://github.com/AppsFlyerSDK/appsflyer-unity-plugin.git#Strict-upm\"\n```\n5. Download the [External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver) to be able to resolve our Android / iOS dependencies.\n\n**Note:** To choose an earlier version and not the latest, you can replace the `upm` or `Strict-upm` with the specific version, `v6.10.30` for the regular version of 6.10.30 or `Strict-v6.10.30` for the Strict version of 6.10.30.\n\n---\n\n# Installation without unity-jar-resolver\n  \n  * If you do not wish to include [The External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver) then follow these steps:\n  1. import `appsflyer-unity-plugin.v*.unitypackage` to your project but make sure to uncheck the `EDM4U` dependencies.\n  <img src=\"https://user-images.githubusercontent.com/61788924/199495968-7aa911ed-27c4-4e5b-a496-3771d0405fd4.jpeg\"  width=\"350\">\n\n  2. Download and add the required Android dependencies to the Assets/Plugins/Android folder:\n      1. [AppsFlyer Android SDK](https://repo1.maven.org/maven2/com/appsflyer/af-android-sdk/6.17.6/af-android-sdk-6.17.6.aar)\n      2. [AppsFlyer Unity Wrapper](https://repo1.maven.org/maven2/com/appsflyer/unity-wrapper/6.17.90/unity-wrapper-6.17.90.aar) — Billing Library 7, or [unity-wrapper-6.17.91](https://repo1.maven.org/maven2/com/appsflyer/unity-wrapper/6.17.91/unity-wrapper-6.17.91.aar) for Billing Library 8\n      3. [Google Installreferrer library](https://mvnrepository.com/artifact/com.android.installreferrer/installreferrer/2.1)\n  3. Download and add the required iOS dependencies to the Assets/Plugins/iOS/AppsFlyer folder:\n      1. [Download](https://github.com/AppsFlyerSDK/AppsFlyerFramework/releases/tag/6.17.9) the iOS SDK as a static library `AppsFlyerLib.xcframework.zip`\n      2. Unzip the file you downloaded\n      3. Drag & drop all the files into the `Assets/Plugins/iOS/AppsFlyer` folder\n"
  },
  {
    "path": "docs/Introduction.md",
    "content": "---\ntitle: Introduction\nslug: \"introduction-unity\"\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 0\nhidden: false\n---\n\n<img src=\"https://massets.appsflyer.com/wp-content/uploads/2018/06/20092440/static-ziv_1TP.png\"  width=\"400\" >\n\n# appsflyer-unity-plugin\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![GitHub tag](https://img.shields.io/github/v/release/AppsFlyerSDK/appsflyer-unity-plugin)](https://img.shields.io/github/v/release/AppsFlyerSDK/appsflyer-unity-plugin)\n[![Unit tests](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/actions/workflows/main.yml/badge.svg)](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/actions/workflows/main.yml)\n[![check packages](https://github.com/af-margot/appsflyer-unity-plugin-beta/actions/workflows/checksums_files.yml/badge.svg)](https://github.com/af-margot/appsflyer-unity-plugin-beta/actions/workflows/checksums_files.yml)\n\n\n🛠 In order for us to provide optimal support, please contact AppsFlyer support through the Customer Assistant Chatbot for assistance with troubleshooting issues or product guidance. </br>\nTo do so, please follow [this article](https://support.appsflyer.com/hc/en-us/articles/23583984402193-Using-the-Customer-Assistant-Chatbot)\n\n## ButterFlyer Sample App\n\n<a href=\"https://github.com/AppsFlyerSDK/appsflyer-unity-sample-app\">ButterFlyer - Unity Sample App\n\n![](https://files.readme.io/3cdc241-banner-butterflyer.png \"banner-butterflyer.png\")\n\n</a>\n\n## Plugin Github Repository\n\n<a style=\"display: none\" href=\"https://github.com/AppsFlyerSDK/appsflyer-unity-plugin\"></a>\n\n> 📘 Github repository for this plugin is [here](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin)\n\n### <a id=\"plugin-build-for\"> This plugin is built for\n\n- Android AppsFlyer SDK v6.17.5\n- Android Purchase Connector 2.2.0\n- iOS AppsFlyer SDK v6.17.8\n- iOS Purchase Connector 6.17.8\n---\n\n## 📌 Important: Two Versions of Unity Plugin v6.17.7\n\nWe have released **two** versions of the AppsFlyer Unity plugin to support teams at different stages of migrating to **Google Play Billing Library v8.0.0**.\n\n### Option A — `v6.17.81` (Billing Library v8)\n- **What's included:** Support for **Google Play Billing Library 8.0.0** on Android (Android Purchase Connector version - 2.2.0).\n- **Impact:** This version may introduce **breaking changes** for apps that have **not yet migrated** to the Billing v8 APIs.\n- **Unity IAP requirement:** If you choose this option, update **Unity IAP (`com.unity.purchasing`) to version 5.0.0 or newer** (we recommend the latest 5.x). Unity IAP 4.x does **not** include Billing v8.\n\n### Option B — `v6.17.80` (Billing Library v7)\n- **Purpose:** For developers **not ready** to adopt Billing v8.\n- **Bundled SDKs:** **iOS SDK 6.17.8** and **Android SDK 6.17.5**.\n- **Android Purchase Connector:** Version 2.1.2\n- **Impact:** Lets you update the AppsFlyer SDKs without changing your existing (pre‑v8) billing integration.\n\n---  \n## <a id=\"new-in-6171\">     🎉 New in 6.17.1 - Purchase Connector Integration \n- Starting from version 6.17.1, the **Purchase Connector is now integrated directly into the main AppsFlyer Unity plugin**. You no longer need to download, import, or maintain a separate Purchase Connector package.\n- If you were previously using the standalone Purchase Connector from a separate repository, simply remove any references to `using AppsFlyerConnector;` from your codebase, as its functionality is now included in the main plugin under the `AppsFlyerSDK` namespace.\n- The Purchase Connector now supports **StoreKit 2** for iOS 15+ alongside the existing StoreKit 1 support.\n- For detailed migration instructions and new features, see our [Purchase Connector documentation](/docs/purchase-connector.md).\n\n---\n## <a id=\"breaking-changes-6175\">     ❗❗ Breaking changes when updating to 6.17.5 ❗❗\n- **In-App Purchase Validation API Changes**: The `validateAndSendInAppPurchase` method signatures have been updated for better type safety and cleaner code.\n- **V2 Methods (Recommended)**: New overloads using structured data classes (`AFPurchaseDetailsAndroid`/`AFSDKPurchaseDetailsIOS`) are now the recommended approach.\n- **Legacy Methods (Deprecated)**: The old string-based parameter methods are now deprecated but maintained for backward compatibility.\n- **Migration Required**: If you're using the old `validateAndSendInAppPurchase` methods, consider migrating to the V2 versions for better maintainability.\n- For detailed API documentation and migration examples, see our [API reference](/docs/API.md).\n\n---  \n## <a id=\"breaking-changes\">     ❗❗ Breaking changes when updating to 6.12.20 ❗❗\n- Starting from version 6.12.20, we have changed the way we distribute the plugin via UPM. The UPM branches will no longer hold a dependency for `com.google.external-dependency-manager` as it was proved to cause issues in different versions of Unity - to be clear, this dependency is still required to utilize our plugin, we just can't distribute the plugin with it in UPM form as the EDM4U dependency is [not available via UPM for quite a while already](https://github.com/googlesamples/unity-jar-resolver/issues/434#issuecomment-827028132) but is still available via `.unitypackage` or `.tgz` files, if you use UPM to fetch our plugin - [please download a suitable version of EDM4U](https://github.com/googlesamples/unity-jar-resolver) so you will be able to resolve the dependencies, or opt for [an installation without EDM4U](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/docs/Installation.md#installation-without-unity-jar-resolver).\n---  \n\n## <a id=\"breaking-changes\">     ❗❗ Breaking changes when updating to 6.6.0 ❗❗\n- Starting version 6.6.0, there is no more need to differentiate between iOS and Android APIs. All APIs must be called with `AppsFlyer` class (even if the API is only iOS or Android).\n- Please take into consideration that since version 6.6.0, most of the APIs require `initSDK` to be called prior to using them, and since version 6.10.10 only a handful of APIs will properly work when called prior to initialization: `setIsDebug`, `setCurrencyCode`, `setHost`, `disableSKAdNetwork`.\n\nExample:\n\nBefore 6.6.0:\n```c#\n#if UNITY_IOS && !UNITY_EDITOR\n    AppsFlyeriOS.waitForATTUserAuthorizationWithTimeoutInterval(60);\n#endif\n```\n---\n\nAfter 6.6.0:\n```c#\n#if UNITY_IOS && !UNITY_EDITOR\n    AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(60);\n#endif\n```\n---\n\n## <a id=\"strict-mode\"> Strict Mode\nThe plugin supports a Strict Mode which completely removes the IDFA collection functionality and AdSupport framework dependencies.\nUse the Strict Mode when developing apps for kids, for example.\nMore information about how to install the Strict Mode is available [here](/docs/Installation.md).\n\n\n### <a id=\"init-sdk-deeplink\"> AD_ID permission for Android\n\nIn v6.8.0 of the AppsFlyer SDK, we added the normal permission com.google.android.gms.permission.AD_ID to the SDK's AndroidManifest, to allow the SDK to collect the Android Advertising ID on apps targeting API 33. If your app is targeting children, you need to revoke this permission to comply with Google's Data policy. You can read more about it [here](https://dev.appsflyer.com/hc/docs/install-android-sdk#the-ad_id-permission).\n\n\n\n ---\n## <a id=\"plugin-build-for\"> 🚀 Getting Started\n- [Installation](/docs/Installation.md)\n- [Integration](/docs/BasicIntegration.md)\n- [Test integration](/docs/Testing.md)\n- [In-app events](/docs/InAppEvents.md)\n- [Send Consent for DMA Compliance](/docs/DMAConsent.md)\n- [Uninstall measurement](/docs/UninstallMeasurement.md)\n## <a id=\"plugin-build-for\"> 💰 Purchase Connector\n- [Purchase Connector (ROI360)](/docs/purchase-connector.md)\n## <a id=\"plugin-build-for\"> 🔗 Deep Linking\n- [Integration](/docs/DeepLinkIntegrate.md)\n- [Unified Deep Link (UDL)](/docs/UnifiedDeepLink.md)\n- [User invite](/docs/UserInvite.md)\n## <a id=\"plugin-build-for\"> 🧪 Sample App\n- [ButterFlyer](https://github.com/AppsFlyerSDK/appsflyer-unity-sample-app)\n\n----  \n### [API reference](/docs/API.md)    \n### [Troubleshooting](/docs/Troubleshooting.md)"
  },
  {
    "path": "docs/MigrationGuide.md",
    "content": "---\r\ntitle: Migration guide from v4\r\ncategory: 5f9705393c689a065c409b23\r\nparentDoc: 6370c9e2441a4504d6bca3bd\r\norder: 11\r\nhidden: false\r\n---\r\n\r\n1. [Remove the old Plugin](#remove-the-old-plugin)\r\n2. [Init the new Plugin](#init-the-new-plugin)\r\n3. [Update deeplink logic](#update-deeplink-logic)\r\n4. [Update code](#update-other-code)\r\n\r\n:warning: There are breaking changes when migrating to Unity v5. This includes:\r\n* New class names\r\n* New android package name\r\n* `com.appsflyer.GetDeepLinkingActivity` does not exist in Unity v5. This is no longer required for deeplinking\r\n* unity-jar-resolver is used to import assets\r\n\r\n# Remove the old plugin \r\n\r\n1. Remove all the items contained in `AppsFlyerUnityPlugin_v4.x.x.unitypackage`\r\n\r\nHere is a list of all the filed included:\r\n\r\n```\r\nAssets/Plugins/AppsFlyer.cs\r\nAssets/Plugins/AFInAppEvents.cs\r\nAssets/Plugins/AppsFlyerTrackerCallbacks.cs\r\n---\r\nAssets/Plugins/Android/AppsFlyerAndroidPlugin.jar \r\nAssets/Plugins/Android/AF-Android-SDK.jar \r\nAssets/Plugins/Android/installreferrer-1.0.aar\r\n---\r\nAssets/Plugins/iOS/AppsFlyerAppController.mm\r\nAssets/Plugins/iOS/AppsFlyerCrossPromotionHelper.h\r\nAssets/Plugins/iOS/AppsFlyerDelegate.h\r\nAssets/Plugins/iOS/AppsFlyerDelegate.mm\r\nAssets/Plugins/iOS/AppsFlyerLinkGenerator.h\r\nAssets/Plugins/iOS/AppsFlyerShareInviteHelper.h\r\nAssets/Plugins/iOS/AppsFlyerTracker.h\r\nAssets/Plugins/iOS/AppsFlyerWrapper.h\r\nAssets/Plugins/iOS/AppsFlyerWrapper.mm\r\nAssets/Plugins/iOS/libAppsFlyerLib.a\r\n\r\n```\r\n\r\n# Init the new plugin\r\n    \r\n1. Add the new .unitypackage, which can be found in the new plugin. \r\n    \r\n2. There are two main options of initialization: \r\n   1. Remove all old init code and use the new .prefab object. \r\n   2. Update your existing init code.\r\n   \r\n## 1. remove all old init code \r\nTo do this simpily remove the game object or all the appsflyer code in the game object where there sdk is being initalized.\r\nThen follow the init guide for the new plugin.\r\n    \r\n## 2. Update old init code with new code\r\n\r\nReplace old init code:\r\n\r\n```c#\r\nvoid Start () {\r\n    AppsFlyer.setAppsFlyerKey(\"K2***********99\");\r\n    /* AppsFlyer.setIsDebug(true); */\r\n#if UNITY_IOS\r\n  AppsFlyer.setAppID(\"41******85\");\r\n  AppsFlyer.trackAppLaunch();\r\n  AppsFlyer.getConversionData();\r\n#elif UNITY_ANDROID\r\n  AppsFlyer.setAppID (\"com.appsflyer.test\");\r\n  AppsFlyer.init(\"K2**********99\",\"AppsFlyerTrackerCallbacks\");\r\n#endif\r\n}\r\n```\r\n\r\nWith new init code:\r\n\r\n\r\n```c#\r\nusing AppsFlyerSDK;\r\n\r\npublic class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData\r\n{\r\n    void Start()\r\n    {\r\n        /* AppsFlyer.setDebugLog(true); */\r\n        AppsFlyer.init-sdk(\"devkey\", \"appID\", this);\r\n        AppsFlyer.startSDK();\r\n    }\r\n    \r\n // .....   \r\n}\r\n```\r\n**Important**\r\nIf you are also implementing conversion data and/or deeplinking then you need to initialize the SDK with the `IAppsFlyerConversionData` interface.\r\n\r\n## Update deeplink logic \r\n    \r\nUnity v5 does not include `com.appsflyer.GetDeepLinkingActivity`. <br>This was used in Unity v4 as a workaround for deeplinking.<br>\r\nIf you are using this class for deeplinking, then make sure to remove the GetDeepLinkingActivity from the AndroidManifest.xml file. \r\n\r\n## Update other Code\r\n\r\nHere is a list of all the old API, and the new API.\r\n\r\n**API**\r\n\r\n- [setAppsFlyerKey](#init-sdk)\r\n- [trackAppLaunch](#init-sdk)\r\n- [setAppID](#init-sdk)\r\n- [getConversionData](#init-sdk)\r\n- [init](#init-sdk)\r\n- [loadConversionData](#init-sdk)\r\n- [setCurrencyCode](#api-that-did-not-change)\r\n- [setCustomerUserID](#api-that-did-not-change)\r\n- [setAdditionalData](#api-that-did-not-change)\r\n- [trackCrossPromoteImpression](#api-that-did-not-change)\r\n- [setMinTimeBetweenSessions](#api-that-did-not-change)\r\n- [setHost](#api-that-did-not-change)\r\n- [setUserEmails](#api-that-did-not-change)\r\n- [setResolveDeepLinkURLs](#api-that-did-not-change)\r\n- [setOneLinkCustomDomain](#api-that-did-not-change)\r\n- [trackRichEvent](#updated-core-api)\r\n- [stopTracking](#updated-core-api)\r\n- [setIsDebug](#api-that-did-not-change)\r\n- [getAppsFlyerId](#api-that-did-not-change)\r\n- [setDeviceTrackingDisabled](#updated-core-api)\r\n- [setAppInviteOneLinkID](#api-that-did-not-change)\r\n- [generateUserInviteLink](#updated-core-api)\r\n- [trackAndOpenStore](#updated-core-api)\r\n- [setIsSandbox](#ios-only-api)\r\n- [registerUninstall](#ios-only-api)\r\n- [setCollectIMEI](#android-only-api)\r\n- [setCollectAndroidID](#android-only-api)\r\n- [setImeiData](#android-only-api)\r\n- [updateServerUninstallToken](#android-only-api)\r\n- [setAndroidIdData](#android-only-api)\r\n- [setPreinstallAttribution](#android-only-api)\r\n- [validate-receipt (ios)](#validate-receipt)\r\n- [validate-receipt (android)](#validate-receipt)\r\n- [createValidateInAppListener](#validate-receipt)\r\n- [handlePushNotification](#deprecated)\r\n- [enableUninstallTracking](#deprecated)\r\n- [handleOpenUrl](#deprecated)\r\n- [getHost](#deprecated)\r\n- [loadConversionData](#deprecated)\r\n- [setGCMProjectNumber](#deprecated)\r\n- [setShouldCollectDeviceName](#deprecated)\r\n\r\n\r\n## Init SDK\r\n```c#\r\n// Old API's\r\nAppsFlyer.setAppsFlyerKey(string key);\r\nAppsFlyer.trackAppLaunch();\r\nAppsFlyer.setAppID(string appleAppId);\r\nAppsFlyer.getConversionData ();\r\nAppsFlyer.init(string devKey);\r\nAppsFlyer.init(string devKey, string callbackObject);\r\nAppsFlyer.loadConversionData(string callbackObject);\r\n\r\n// New API's\r\nAppsFlyer.initSDK(string key, string app_id); // without deeplinking/conversion data\r\nAppsFlyer.initSDK(string key, string app_id, MonoBehaviour gameObject); // with deeplinking/conversion data\r\nAppsFlyer.startSDK();\r\n```\r\n\r\n## API that did not change\r\n```c#\r\nAppsFlyer.setCurrencyCode(string currencyCode);\r\nAppsFlyer.setCustomerUserID(string customerUserID);\r\nAppsFlyer.setAdditionalData(Dictionary<string, string> extraData);\r\nAppsFlyer.trackCrossPromoteImpression(string appId, string campaign);\r\nAppsFlyer.setMinTimeBetweenSessions(int seconds);\r\nAppsFlyer.setHost(string hostPrefixName, string hostName);\r\nAppsFlyer.setUserEmails(EmailCryptType cryptType, params string[] userEmails);\r\nAppsFlyer.setResolveDeepLinkURLs(params string[] userEmails);\r\nAppsFlyer.setOneLinkCustomDomain(params string[] domains);\r\nAppsFlyer.setIsDebug(bool isDebug);\r\nAppsFlyer.getAppsFlyerId();\r\nAppsFlyer.setAppInviteOneLinkID(string oneLinkID);\r\n```\r\n\r\n## Updated core API\r\n```c#\r\n// old\r\nAppsFlyer.trackRichEvent(string eventName, Dictionary<string, string> eventValues);\r\n// new\r\nAppsFlyer.sendEvent(string eventName, Dictionary<string, string> eventValues);\r\n\r\n// old\r\nAppsFlyer.stopTracking(bool isStopTracking);\r\n// new\r\nAppsFlyer.stopSDK(bool isStopTracking);\r\n   \r\n// old   \r\nAppsFlyer.setDeviceTrackingDisabled(bool state);\r\n// new   \r\nAppsFlyer.anonymizeUser(true);\r\n\r\n// old \r\nAppsFlyer.generateUserInviteLink(Dictionary<string,string> parameters, string callbackObject,string callbackMethod, string callbackFailedMethod);\r\n// new\r\nAppsFlyer.generateUserInviteLink(Dictionary<string, string> parameters, MonoBehaviour gameObject);\r\n    \r\n// old \r\nAppsFlyer.trackAndOpenStore(string promotedAppId, string campaign, Dictionary<string,string> customParams);\r\n// new \r\nAppsFlyer.trackAndOpenStore(string appID, string campaign, Dictionary<string, string> userParams, MonoBehaviour gameObject);\r\n```\r\n\r\n## iOS Only API\r\n```c#\r\n// old\r\nAppsFlyer.setIsSandbox(bool isSandbox);\r\n// new\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.setUseReceiptValidationSandbox(true);\r\n#endif\r\n\r\n// old\r\nAppsFlyer.registerUninstall(byte[] token);\r\n// new\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.registerUninstall(token);\r\n#endif\r\n\r\n// old\r\nAppsFlyer.handleOpenUrl(string url, string sourceApplication, string annotation);\r\n// new\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.handleOpenUrl(string url, string sourceApplication, string annotation);\r\n#endif\r\n```\r\n\r\n\r\n## Android Only API\r\n\r\n```c#\r\n// old\r\nAppsFlyer.setCollectIMEI(bool shouldCollect);\r\n// new \r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCollectIMEI(bool shouldCollect);\r\n#endif\r\n\r\n// old\r\nAppsFlyer.setCollectAndroidID(bool shouldCollect);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setCollectAndroidID(bool shouldCollect);\r\n#endif\r\n\r\n//old\r\nAppsFlyer.setImeiData(string imeiData);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setImeiData(string imeiData);\r\n#endif\r\n\r\n//old\r\nAppsFlyer.updateServerUninstallToken(string token);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.updateServerUninstallToken(string token);\r\n#endif\r\n\r\n//old\r\nAppsFlyer.setAndroidIdData(string androidIdData);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppAppsFlyersFlyerAndroid.setAndroidIdData(\"androidId\");\r\n#endif\r\n\r\n//old\r\nAppsFlyer.setPreinstallAttribution(string mediaSource, string campaign, string siteId);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.setPreinstallAttribution(\"mediaSource\", \"campaign\", \"siteId\");\r\n#endif\r\n\r\n//old\r\nAppsFlyer.handlePushNotification(Dictionary<string, string> payload);\r\n//new\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.handlePushNotifications();\r\n#endif\r\n```\r\n\r\n## Validate Receipt\r\n\r\n```c#\r\n// android old api\r\nAppsFlyer.validate-receipt(string publicKey, string purchaseData, string signature, string price, string currency, Dictionary<string, string> extraParams);\r\n\r\n // iOS old api\r\nAppsFlyer.validate-receipt(string productIdentifier, string price, string currency, string transactionId, Dictionary<string, string> additionalParametes);\r\nAppsFlyer.createValidateInAppListener(string aObject, string callbackMethod, string callbackFailedMethod);  \r\n\r\n// ⚠️ Deprecated: Use V2 version with AFPurchaseDetailsAndroid instead\r\n#if UNITY_ANDROID && !UNITY_EDITOR\r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        \"publicKey\", \r\n        \"signature\", \r\n        \"purchaseData\", \r\n        \"price\", \r\n        \"currency\", \r\n        null, \r\n        this);\r\n#endif\r\n\r\n// ⚠️ Deprecated: Use V2 version with AFSDKPurchaseDetailsIOS instead\r\n#if UNITY_IOS && !UNITY_EDITOR\r\n        AppsFlyer.validateAndSendInAppPurchase(\r\n        \"productIdentifier\", \r\n        \"price\", \r\n        \"currency\", \r\n        \"tranactionId\", \r\n        null, \r\n        this);\r\n#endif\r\n```\r\n\r\n## Deprecated\r\n    \r\n```c#\r\n//@Deprecated\r\nAppsFlyer.enableUninstallTracking(string senderId);\r\nAppsFlyer.getHost();\r\nAppsFlyer.loadConversionData(string callbackObject, string callbackMethod, string callbackFailedMethod);\r\nAppsFlyer.setGCMProjectNumber(string googleGCMNumber);\r\nAppsFlyer.setShouldCollectDeviceName(bool shouldCollectDeviceName);\r\n```\r\n\r\n\r\n"
  },
  {
    "path": "docs/PushNotifications.md",
    "content": "---\ntitle: Push Notifications\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 9\nhidden: false\n---\n\n## Unity push notifications using OneLink & Firebase\n\n<span class=\"annotation-recommended\">Recommended</span>  \nThis is the recommended method for implementing push notification measurement in the Unity Appsflyer SDK.\n\n**To integrate AppsFlyer with Android push notifications:**\n\n1. In your `AppsFlyerObjectScript.cs`, call `addPushNotificationDeepLinkPath` **before** calling `start`:\n\n```csharp\nAppsFlyer.addPushNotificationDeepLinkPath(\"af_push_link\");\n```\n\nIn the example above, the SDK is configured to look for the `af_push_link` key in the first level of the push notification payload.  \nWhen calling `addPushNotificationDeepLinkPath` the SDK verifies that:\n\n- The required key exists in the payload.\n- The key contains a valid OneLink URL.\n\n> 📘 Note\n> \n> `addPushNotificationDeepLinkPath` accepts an array of strings too, to allow you to extract the relevant key from nested JSON structures. For more information, see [`addPushNotificationDeepLinkPath`](https://dev.appsflyer.com/hc/docs/api#addpushnotificationdeeplinkpath).\n\n2. Create a new Firebase Unity app and follow the [Firebase guide](https://firebase.google.com/docs/unity/setup) (Import the SDK package and the GoogleService files to Unity)\n3. Create FirebaseManager empty object and add `FirebaseManager.cs` to it: \n\n```csharp\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\nusing Firebase.Extensions;\nusing System;\nusing System.Threading.Tasks;\nusing AppsFlyerSDK;\n\npublic class FirebaseManager : MonoBehaviour\n{\n    private Vector2 scrollViewVector = Vector2.zero;\n    private string logText = \"\";\n    const int kMaxLogSize = 16382;\n    Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;\n    protected bool isFirebaseInitialized = false;\n    private string topic = \"TestTopic\";\n\n    // Log the result of the specified task, returning true if the task\n    // completed successfully, false otherwise.\n    protected bool LogTaskCompletion(Task task, string operation)\n    {\n        bool complete = false;\n        if (task.IsCanceled)\n        {\n            DebugLog(operation + \" canceled.\");\n        }\n        else if (task.IsFaulted)\n        {\n            DebugLog(operation + \" encounted an error.\");\n            foreach (Exception exception in task.Exception.Flatten().InnerExceptions)\n            {\n                string errorCode = \"\";\n                Firebase.FirebaseException firebaseEx = exception as Firebase.FirebaseException;\n                if (firebaseEx != null)\n                {\n                    errorCode = String.Format(\"Error.{0}: \",\n                      ((Firebase.Messaging.Error)firebaseEx.ErrorCode).ToString());\n                }\n                DebugLog(errorCode + exception.ToString());\n            }\n        }\n        else if (task.IsCompleted)\n        {\n            DebugLog(operation + \" completed\");\n            complete = true;\n        }\n        return complete;\n    }\n\n\n    // When the app starts, check to make sure that we have\n    // the required dependencies to use Firebase, and if not,\n    // add them if possible.\n    protected virtual void Start()\n    {\n        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>\n        {\n            dependencyStatus = task.Result;\n            if (dependencyStatus == Firebase.DependencyStatus.Available)\n            {\n                InitializeFirebase();\n            }\n            else\n            {\n                Debug.LogError(\n                  \"Could not resolve all Firebase dependencies: \" + dependencyStatus);\n            }\n        });\n    }\n\n    // Setup message event handlers.\n    void InitializeFirebase()\n    {\n        Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;\n        Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;\n        Firebase.Messaging.FirebaseMessaging.SubscribeAsync(topic).ContinueWithOnMainThread(task =>\n        {\n            LogTaskCompletion(task, \"SubscribeAsync\");\n        });\n        DebugLog(\"Firebase Messaging Initialized\");\n\n        // This will display the prompt to request permission to receive\n        // notifications if the prompt has not already been displayed before. (If\n        // the user already responded to the prompt, thier decision is cached by\n        // the OS and can be changed in the OS settings).\n        Firebase.Messaging.FirebaseMessaging.RequestPermissionAsync().ContinueWithOnMainThread(\n          task =>\n          {\n              LogTaskCompletion(task, \"RequestPermissionAsync\");\n          }\n        );\n        isFirebaseInitialized = true;\n    }\n\n    public virtual void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)\n    {\n        DebugLog(\"Received a new message\");\n        var notification = e.Message.Notification;\n        if (notification != null)\n        {\n            DebugLog(\"title: \" + notification.Title);\n            DebugLog(\"body: \" + notification.Body);\n            var android = notification.Android;\n            if (android != null)\n            {\n                DebugLog(\"android channel_id: \" + android.ChannelId);\n            }\n        }\n        if (e.Message.From.Length > 0)\n            DebugLog(\"from: \" + e.Message.From);\n        if (e.Message.Link != null)\n        {\n            DebugLog(\"link: \" + e.Message.Link.ToString());\n        }\n        if (e.Message.Data.Count > 0)\n        {\n            DebugLog(\"data:\");\n            foreach (System.Collections.Generic.KeyValuePair<string, string> iter in\n                     e.Message.Data)\n            {\n                DebugLog(\"  \" + iter.Key + \": \" + iter.Value);\n            }\n        }\n#if UNITY_IOS && !UNITY_EDITOR\n        DebugLog(\"DidReceivedDeepLink: true\");\n        appsFlyerObj.DidReceivedDeepLink = true;\n        var dataDict = new Dictionary<string, string>(e.Message.Data);\n        AppsFlyeriOS.handlePushNotification(dataDict);\n#endif\n    }\n\n    public virtual void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)\n    {\n        DebugLog(\"Received Registration Token: \" + token.Token);\n    }\n\n    public void ToggleTokenOnInit()\n    {\n        bool newValue = !Firebase.Messaging.FirebaseMessaging.TokenRegistrationOnInitEnabled;\n        Firebase.Messaging.FirebaseMessaging.TokenRegistrationOnInitEnabled = newValue;\n        DebugLog(\"Set TokenRegistrationOnInitEnabled to \" + newValue);\n    }\n\n    // Exit if escape (or back, on mobile) is pressed.\n    protected virtual void Update()\n    {\n        if (Input.GetKeyDown(KeyCode.Escape))\n        {\n            Application.Quit();\n        }\n    }\n\n    // End our messaging session when the program exits.\n    public void OnDestroy()\n    {\n        Firebase.Messaging.FirebaseMessaging.MessageReceived -= OnMessageReceived;\n        Firebase.Messaging.FirebaseMessaging.TokenReceived -= OnTokenReceived;\n    }\n\n    // Output text to the debug log text field, as well as the console.\n    public void DebugLog(string s)\n    {\n        print(s);\n        logText += s + \"\\n\";\n\n        while (logText.Length > kMaxLogSize)\n        {\n            int index = logText.IndexOf(\"\\n\");\n            logText = logText.Substring(index + 1);\n        }\n\n        scrollViewVector.y = int.MaxValue;\n    }\n}\n```\n\n> 📘 Note\n> \n> In the `OnMessageReceived` function, for iOS specifically, we are calling the `AppsFlyeriOS.handlePushNotification(Dictionary<string, string> pushPayload)` method ([read more](https://dev.appsflyer.com/hc/docs/api#addpushnotificationdeeplinkpath)) in order to trigger the AppsFlyerSDK method that is getting overridden due to Firebase's swizzling.\n\n## iOS\n\n1. Add an [APN Authentication key](https://firebase.google.com/docs/cloud-messaging/ios/client#upload_your_apns_authentication_key) to your Firebase Unity iOS app  \n   ![Firebase - project setting - cloud messeging](https://files.readme.io/a3e7231-Screenshot_2023-05-30_at_18.35.30.png)\n2. After building your project, open the XCode project and add the following capabilities:\n   - Push Notifications\n   - Background Modes -> Remote Notifications\n   - Associated Domains (for UDL) - [read more](https://developer.apple.com/documentation/xcode/supporting-associated-domains)\n3. If you are getting errors when building the app due to bitcode, disable bitcode\n\n## Android\n\n1. In the AndroidManifest: Add the following service:\n   ```xml\n   <service android:name=\"com.google.firebase.messaging.MessageForwardingService\"\n               android:permission=\"android.permission.BIND_JOB_SERVICE\" android:exported=\"true\" />\n   ```\n2. Create a Keystore and a key for your app and generate the SHA1 fingerprint ([and the SHA256 fingerprint for Android App Links](https://dev.appsflyer.com/hc/docs/dl_android_init_setup#procedures-for-android-app-links)) \n   - SHA1 for Firebase  \n     ![Firebase - app settings - Android app - adding SHA1 fingerprint](https://files.readme.io/0bfbfe6-Screenshot_2023-05-30_at_18.39.06.png)"
  },
  {
    "path": "docs/Testing.md",
    "content": "---\ntitle: Test Integration\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 2\nhidden: false\n---\n\nYou are can test your integration for the following OS:\n\n- [Testing for iOS/Android](#testing-for-iosandroid)\n- [Testing for Windows](#testing-for-windows)\n\n## Testing for iOS/Android\n\nIn order to test the plugin, you need to build an iOS/Android app. Then you can follow these guides: \n- [Marketers](https://support.appsflyer.com/hc/en-us/articles/360001559405-Test-mobile-SDK-integration-with-the-app#introduction).\n- [Android](https://dev.appsflyer.com/hc/docs/testing-android)\n- [iOS](https://dev.appsflyer.com/hc/docs/testing-ios)\n\nTo enable the debug logs, set the following API to true:\n```c#\nAppsFlyer.setIsDebug(true);\n```\n\n---\n\n## Testing for Windows\n\nIn order to test the plugin, you need to build your UWP app.\nTo enable the debug logs, please uncomment the following line in [AppsFlyerWindows.cs](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/d0f1c05d17dc4e400609ca880f5079c31fdee73e/Assets/AppsFlyer/Windows/AppsFlyerWindows.cs#L1) file.\n\n```c#\n#define AFSDK_WIN_DEBUG\n```\n\nAfter running the app, you will be able to find the logs in `%USERPROFILE%\\AppData\\Local\\Packages<productname>\\TempState\\UnityPlayer.log`\n\n"
  },
  {
    "path": "docs/Troubleshooting.md",
    "content": "---\ntitle: Troubleshooting\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 10\nhidden: false\n---\n\n# iOS Swizzling \n\n* AppsFlyer Unity Plugin uses the [iOS life cycle](https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle) events for the SDK to work. \n* The plugins uses [UnityAppController](https://docs.unity3d.com/Manual/UnityasaLibrary-iOS.html) for the lifecycle events to be invoked.\n* Sometimes other plugins (Firebase, Facebook, ect) use the same UnityAppController, which creates conflicts in the lifecycle events.\n* These events include didBecomeActive, didEnterBackground, didReceiveRemoteNotification, continueUserActivity and openURL.\n* When a conflict occurs these methods may not be invoked. \n* The solution provided by the AppsFlyer Unity Plugin is [Swizzling](https://medium.com/rocknnull/ios-to-swizzle-or-not-to-swizzle-f8b0ed4a1ce6).\n* Starting from `v6.0.7` there is an option to enable swizzling automatically. \n\nTo enable Swizzling, you have 3 options: \n* For versions up to `6.5.3`\n    - [Using info .plist](#using-info-plist)\n    - [Using a c# Script](#using-a-c-script)\n* From version `6.5.3`\n    - [Using macroprocessor starting v6.5.3](#using-macroprocessor)\n\n\n## Using info .plist\n\n* To enable swizzling, in the info.plist file, a boolean K/V called `AppsFlyerShouldSwizzle` should be set to 1 (true).\n* This will automatically enable swizzling and solve conflicts with other plugins.\n* Validate that the code in the [AppsFlyer+AppController](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/Assets/AppsFlyer/Plugins/iOS/AppsFlyer%2BAppController.m) is called on the native side.\n* Comment out `IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)` in AppsFlyerAppController.mm.\n\n---\n\n## Using a c# Script\n1. Create a new c# script. (we called ours AFUpdatePlist.cs)\n2. Place the script in a editor folder (Assets > Editor > AFUpdatePlist.cs)\n3. The code in the script should look like this:\n\n```c#\nusing System.IO;\nusing UnityEngine;\nusing UnityEditor;\nusing UnityEditor.Callbacks;\nusing UnityEditor.iOS.Xcode;\n\npublic class MyBuildPostprocessor {\n    \n    [PostProcessBuildAttribute]\n    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {\n        \n        if (target == BuildTarget.iOS)\n        {\n            string plistPath = pathToBuiltProject + \"/Info.plist\";\n            PlistDocument plist = new PlistDocument();\n            plist.ReadFromString(File.ReadAllText(plistPath));\n            \n            PlistElementDict rootDict = plist.root;\n            rootDict.SetBoolean(\"AppsFlyerShouldSwizzle\", true);\n            \n            File.WriteAllText(plistPath, plist.WriteToString());\n            \n            Debug.Log(\"Info.plist updated with AppsFlyerShouldSwizzle\");\n        }\n        \n    }\n}\n```\n\n4. Validate that the code in the [AppsFlyer+AppController](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/Assets/AppsFlyer/Plugins/iOS/AppsFlyer%2BAppController.m) is called on the native side.\n5. Comment out `IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)` in AppsFlyerAppController.mm.\n\n---\n\n## Using macroprocessor\n* Add the [preprocessor macro](https://stackoverflow.com/a/26928784) flag `​AFSDK_SHOULD_SWIZZLE=1` to the build settings of the project. \n\n![alt text](https://user-images.githubusercontent.com/61788924/199495968-7aa911ed-27c4-4e5b-a496-3771d0405fd4.jpeg)\n\n* Validate that the code in the [AppsFlyer+AppController](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin/blob/master/Assets/AppsFlyer/Plugins/iOS/AppsFlyer%2BAppController.m) is called on the native side.\n    \n--- \n    \n# Updating the info.plist\nIn this example, we will update the info.plist to send SKAN postbacks to AppsFlyer, but the script can be adjusted to update any key in the info.plist\n    \n1. Create a new c# script. (we called ours AFUpdatePlist.cs)\n2. Place the script in a editor folder (Assets > Editor > AFUpdatePlist.cs)\n3. The code in the script should look like this:\n\n```c#\nusing System.IO;\nusing UnityEngine;\nusing UnityEditor;\nusing UnityEditor.Callbacks;\nusing UnityEditor.iOS.Xcode;\n\npublic class MyBuildPostprocessor\n{\n\n    [PostProcessBuildAttribute]\n    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)\n    {\n\n        if (target == BuildTarget.iOS)\n        {\n            string plistPath = pathToBuiltProject + \"/Info.plist\";\n            PlistDocument plist = new PlistDocument();\n            plist.ReadFromString(File.ReadAllText(plistPath));\n\n            PlistElementDict rootDict = plist.root;\n            rootDict.SetString(\"NSAdvertisingAttributionReportEndpoint\", \"https://appsflyer-skadnetwork.com/\");\n    \n            /*** To add more keys :\n            ** rootDict.SetString(\"<your key>\", \"<your value>\");\n            ***/\n\n            File.WriteAllText(plistPath, plist.WriteToString());\n\n            Debug.Log(\"Info.plist updated with NSAdvertisingAttributionReportEndpoint\");\n        }\n\n    }\n}\n```\n"
  },
  {
    "path": "docs/UnifiedDeepLink.md",
    "content": "---\ntitle: Unified Deep Linking (UDL)\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 7\nhidden: false\n---\n\n> 📘 **UDL privacy protection**\n> \n> For new users, the UDL method only returns parameters relevant to deferred deep linking: `deep_link_value` and `deep_link_sub1` to `deep_link_sub10`. If you try to get any other parameters (`media_source`, `campaign`, `af_sub1-5`, etc.), they return `null`.\n\n# UDL flow\n\n1. The SDK is triggered by:\n   - **Deferred Deep Linking** - using a dedicated API\n   - **Direct Deep Linking** - triggered by the OS via Android App Link, iOS Universal Links or URI scheme.\n2. The SDK triggers the `OnDeepLink` method, and passes the deep link result object to the user.\n3. The `OnDeepLink` method uses the deep link result object that includes the `deep_link_value` and other parameters to create the personalized experience for the users, which is the main goal of OneLink.\n\n> Check out the Unified Deep Linking docs for [Android](https://dev.appsflyer.com/docs/android-unified-deep-linking) and [iOS](https://dev.appsflyer.com/docs/ios-unified-deep-linking).\n\n# Considerations\n\n* Requires AppsFlyer Android SDK V6.1.3 or later.\n* Does not support SRN campaigns.\n* For new users, the UDL method only returns parameters relevant to deferred deep linking: `deep_link_value` and `deep_link_sub1-10`. If you try to get any other parameters (media_source, campaign, af_sub1-5, etc.), they return `null`.\n* `onAppOpenAttribution` will not be called. All code should migrate to `OnDeepLink`.\n* `OnDeepLink` must be called **after** `initSDK`.\n* `AppsFlyer.cs` **must** be attached to the game object.\n\n# Implementation\n\n1. Attach `AppsFlyer.cs` script to the game object with the AppsFlyer init code. (AppsFlyerObject)\n2. Call initSDK with the `this` parameter in order for the `OnDeepLinkReceived` callback to be invoked:\n    ```c#\n    AppsFlyer.initSDK(\"devkey\", \"appID\", this);\n    ```    \n3. Assign `OnDeepLink` to `AppsFlyer.OnDeepLinkReceived` in `Start()`\n   ```c#\n    AppsFlyer.OnDeepLinkReceived += OnDeepLink;\n   ``` \n4. After `initSDK()` implement `OnDeepLink`.\n\n## Example\n\n```c#\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour\n{\n  void Start()\n  {\n    AppsFlyer.initSDK(\"devkey\", \"appID\", this);\n    AppsFlyer.OnDeepLinkReceived += OnDeepLink;\n    AppsFlyer.startSDK();\n  }\n  \n  void OnDeepLink(object sender, EventArgs args)\n  {\n      var deepLinkEventArgs = args as DeepLinkEventsArgs;\n\n      switch (deepLinkEventArgs.status)\n      {\n          case DeepLinkStatus.FOUND:\n\n              if (deepLinkEventArgs.isDeferred())\n              {\n                  AppsFlyer.AFLog(\"OnDeepLink\", \"This is a deferred deep link\");\n              }\n              else\n              {\n                  AppsFlyer.AFLog(\"OnDeepLink\", \"This is a direct deep link\");\n              }\n              \n              // deepLinkParamsDictionary contains all the deep link parameters as keys\n              Dictionary<string, object> deepLinkParamsDictionary = null;\n      #if UNITY_IOS && !UNITY_EDITOR\n              if (deepLinkEventArgs.deepLink.ContainsKey(\"click_event\") && deepLinkEventArgs.deepLink[\"click_event\"] != null)\n              {\n                  deepLinkParamsDictionary = deepLinkEventArgs.deepLink[\"click_event\"] as Dictionary<string, object>;\n              }\n      #elif UNITY_ANDROID && !UNITY_EDITOR\n                  deepLinkParamsDictionary = deepLinkEventArgs.deepLink;\n      #endif\n\n              break;\n          case DeepLinkStatus.NOT_FOUND:\n              AppsFlyer.AFLog(\"OnDeepLink\", \"Deep link not found\");\n              break;\n          default:\n              AppsFlyer.AFLog(\"OnDeepLink\", \"Deep link error\");\n              break;\n      }\n  }\n}\n\n```\n"
  },
  {
    "path": "docs/UninstallMeasurement.md",
    "content": "---\ntitle: Uninstall Measurement\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 5\nhidden: false\n---\n\n- [iOS](#ios)\n- [Android](#android)\n\n## iOS\n\nAppsFlyer enables you to track app uninstalls. To handle notifications it requires  to modify your `AppDelegate.m`. Use [didRegisterForRemoteNotificationsWithDeviceToken](https://developer.apple.com/reference/uikit/uiapplicationdelegate) to register to the uninstall feature.\n\nUnityEngine.iOS.NotificationServices is now deprecated. Please use the \"Mobile Notifications\" package instead. It is available in the Unity package manager.\n\n*Example:*\n\n```c#\nusing AppsFlyerSDK;\nusing Unity.Notifications.iOS;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, IAppsFlyerConversionData\n{\n\n    void Start()\n    {\n        AppsFlyer.initSDK(\"devKey\", \"appID\", this);\n        AppsFlyer.startSDK();\n#if UNITY_IOS\n  \n        StartCoroutine(RequestAuthorization());\n        Screen.orientation = ScreenOrientation.Portrait;\n\n#endif\n\n    }\n\n\n#if UNITY_IOS\n    IEnumerator RequestAuthorization()\n    {\n      \n        using (var req = new AuthorizationRequest(AuthorizationOption.Alert | AuthorizationOption.Badge, true))\n        {\n\n            while (!req.IsFinished)\n            {\n                yield return null;\n            }\n             if (req.Granted && req.DeviceToken != \"\")\n             {\n                  byte[] tokenBytes = ConvertHexStringToByteArray(req.DeviceToken);\n                  AppsFlyer.registerUninstall(tokenBytes);\n             }\n        }\n    }\n\n    private byte[] ConvertHexStringToByteArray(string hexString)\n    {\n\n        byte[] data = new byte[hexString.Length / 2];\n        for (int index = 0; index < data.Length; index++)\n        {\n            string byteValue = hexString.Substring(index * 2, 2);\n            data[index] = System.Convert.ToByte(byteValue, 16);\n        }\n        return data;\n    }\n#endif\n}\n```\n\nRead more about Uninstall register: [Appsflyer SDK support site](https://support.appsflyer.com/hc/en-us/articles/207032066-AppsFlyer-SDK-Integration-iOS)\n\n---\n\n## Android\n\n1. Download the Unity Firebase SDK from: https://firebase.google.com/docs/unity/setup.\n2. Import FirebaseMessaging.unitypackage into the project.\n3. Import google-services.json into the project (obtained in the Firebase console)\n    **Note** Manifest receivers should be automatically added by the Unity Firebase SDK.\n4. In the Unity class handling the AppsFlyer code, add the following:\n\n```c#\nusing Firebase.Messaging;\nusing Firebase.Unity;\n```\n\n5. Add to the `Start()` method:\n\n```c#\nFirebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;\n```\n\n6. Add the following method:\n\n```c#\n    public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)\n    {\n#if UNITY_ANDROID\n        AppsFlyer.updateServerUninstallToken(token.Token);\n#endif\n    }\n```\n\nRead more about Android  Uninstall Tracking: [Appsflyer SDK support site](https://support.appsflyer.com/hc/en-us/articles/208004986-Android-Uninstall-Tracking)\n\n---\n"
  },
  {
    "path": "docs/UserInvite.md",
    "content": "---\ntitle: User Invite\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 8\nhidden: false\n---\n\n# User invite attribution\n\nAppsFlyer allows you to attribute and record installs originating from user invites within your app. Allowing your existing users to invite their friends and contacts as new users to your app can be a key growth factor for your app.\n\nMore information can be found [here](https://dev.appsflyer.com/hc/docs/dl_user_invite).\n\nExample:\n```c#\n\npublic class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData, IAppsFlyerUserInvite {\n\nvoid Start()\n  {\n    //...\n\n    AppsFlyer.initSDK(\"devkey\", \"appID\");\n    AppsFlyer.setAppInviteOneLinkID(\"XXXX\"); //set up the one link ID for the user invite\n    AppsFlyer.startSDK();\n  }\n   \n\n    //...\n    public void generateAppsFlyerLink()\n    {\n        Dictionary<string, string> parameters = new Dictionary<string, string>();\n        parameters.Add(\"channel\", \"some_channel\");\n        parameters.Add(\"campaign\", \"some_campaign\");\n        parameters.Add(\"additional_param1\", \"some_param1\");\n        parameters.Add(\"additional_param2\", \"some_param2\");\n       \n        // other params\n        //parameters.Add(\"referrerName\", \"some_referrerName\");\n        //parameters.Add(\"referrerImageUrl\", \"some_referrerImageUrl\");\n        //parameters.Add(\"customerID\", \"some_customerID\");\n        //parameters.Add(\"baseDeepLink\", \"some_baseDeepLink\");\n        //parameters.Add(\"brandDomain\", \"some_brandDomain\");\n        \n\n        AppsFlyer.generateUserInviteLink(parameters, this);\n    }\n\n\n    ... \n\n    public void onInviteLinkGenerated(string link)\n    {\n        AppsFlyer.AFLog(\"onInviteLinkGenerated\", link);\n    }\n\n    public void onInviteLinkGeneratedFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onInviteLinkGeneratedFailure\", error);\n    }\n\n    public void onOpenStoreLinkGenerated(string link)\n    {\n        AppsFlyer.AFLog(\"onOpenStoreLinkGenerated\", link);\n    }\n}\n```\n"
  },
  {
    "path": "docs/ad-revenue-unity.md",
    "content": "---\ntitle: \"Ad revenue\"\nslug: \"ad-revenue-unity\"\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\nexcerpt: \"Impression-level ad revenue reporting by SDK\"\nhidden: false\norder: 12\n---\nThe app sends impression revenue data to the SDK which then sends it to AppsFlyer. The revenue data is collected and processed in AppsFlyer, and the revenue is attributed to the original UA source. To learn more about ad revenue see [here](https://support.appsflyer.com/hc/en-us/articles/217490046#connect-to-ad-revenue-integrated-partners).\n\nThere are two ways for the SDK to generate an ad revenue event, depending on your SDK version. Use the correct method for your SDK version:\n- [For SDK 6.15.0 and above](#log-ad-revenue-for-sdk-6150-and-above). Uses the ad revenue SDK API.\n- [For SDK 6.14.2 and below](#legacy-log-ad-revenue-for-sdk-6142-and-below). Uses the ad revenue SDK connector.\n\n## Log ad revenue (for SDK 6.15.0 and above)\n\nWhen an impression with revenue occurs, invoke the [`logAdRevenue`](doc:api#logadrevenue) method with the revenue details of the impression.  \n\n**To implement the method:**\n\n1. Create an instance of `AFAdRevenueData` with the revenue details of the impression to be logged. Version 6.15.0 of the SDK removes the need for using a connector for sending Ad Revenue data to AppsFlyer.\n2. If you want to add additional details to the ad revenue event, populate a map with key-value pairs.\n3. Invoke the  `logAdRevenue` method with the following arguments:\n    - The `AFAdRevenueData` object you created in step 1.\n    - The `Map` instance with the additional details you created in step 2.\n\n### Code Example\n\n```c#\nDictionary<string, string> additionalParams = new Dictionary<string, string>();\nadditionalParams.Add(AdRevenueScheme.COUNTRY, \"USA\");\nadditionalParams.Add(AdRevenueScheme.AD_UNIT, \"89b8c0159a50ebd1\");\nadditionalParams.Add(AdRevenueScheme.AD_TYPE, \"Banner\");\nadditionalParams.Add(AdRevenueScheme.PLACEMENT, \"place\");\nvar logRevenue = new AFAdRevenueData(\"monetizationNetworkEx\", MediationNetwork.GoogleAdMob, \"USD\", 0.99);\nAppsFlyer.logAdRevenue(logRevenue, additionalParams);\n```\n\n> 📘 Note \n>  The AdMob iLTV SDK reports impression revenue in micro-units. To display the correct ad revenue amount in USD in AppsFlyer, divide the amount extracted from the iLTV event handler by 1 million before sending it to AppsFlyer.\n\n## [LEGACY] Log ad revenue (for SDK 6.14.2 and below)\nFor SDK v6.14.2 and below - the AdRevenue Connector should be used along side the AppsFlyer SDK to send Ad Revenue data to AppsFlyer.\n\n### Using Unity Package\n\n1. Clone or download [the Ad revenue connector](https://github.com/AppsFlyerSDK/appsflyer-unity-adrevenue-generic-connector/tree/main) repository.\n2. Import the Adrevenue Unity package into your Unity project (To learn how to import to Unity refer to the [Unity documentation](https://docs.unity3d.com/Manual/AssetPackages.html)).\n   1. In Unity, go to **Assets** > **Import Package** > **Custom Package**\n   2. From the repository root select the  `appsflyer-unity-adrevenue-plugin-x.x.x.unitypackage` file.\n\n### Using Unity Package Manager\n\n1. Add the dependency in your `manifest.json` file:\n\n```\n \"appsflyer-unity-adrevenue-generic-connector\": \"https://github.com/AppsFlyerSDK/appsflyer-unity-adrevenue-generic-connector.git#upm\"\n```\n\n2. If you haven't already done so, download the [External Dependency Manager for Unity](https://github.com/googlesamples/unity-jar-resolver) to be able to resolve our Android / iOS dependencies.\n\n**Note:** To choose a specific version and not the latest, you can replace the `upm` with the specific version tag, `v6.9.4-upm` for example.\n\n### Initialize the connector\n\nMake sure to initialize the AppsFlyer SDK before initializing the connector. \n\n```java\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour\n{\n  void Start()\n  {\n  \tAppsFlyerAdRevenue.start();\n  \t/* AppsFlyerAdRevenue.setIsDebug(true); */\n  }\n}\n\n```\n\n### Ad revenue connector API\n\n#### `start`\n\n`public static void start()`\n\nStart sending AdRevenue data to AppsFlyer.\n\n_Example:_\n\n```java\nusing AppsFlyerSDK;\n  void Start()\n  {\n    AppsFlyerAdRevenue.start();\n  }\n```\n\n#### `setIsDebug`\n\n `public static void setIsDebug(bool isDebug)`\n\nSet to true to view debug logs. (development only!)\n\n| parameter | type | description                     |\n| --------- | ---- | ------------------------------- |\n| isDebug   | bool | set to true in development only |\n\n_Example:_\n\n```java\n  AppsFlyerAdRevenue.setIsDebug(true);\n```\n\n**Note:** This API will only set the debug logs for iOS. For Android the debug logs are controlled by the native SDK.  \nTo turn on the debug logs on Android call `AppsFlyer.setIsDebug(true);`\n\n#### `logAdRevenue`\n\n`public static void logAdRevenue(string monetizationNetwork, AppsFlyerAdRevenueMediationNetworkType mediationNetwork, double eventRevenue, string revenueCurrency, Dictionary<string, string> additionalParameters)`\n\nSend ad revenue data from the impression payload to AppsFlyer regardless of the mediation network you use.\n\n| parameter            | type                                   | description                      |\n| -------------------- | -------------------------------------- | -------------------------------- |\n| monetizationNetwork  | string                                 | monetization network             |\n| mediationNetwork     | AppsFlyerAdRevenueMediationNetworkType | Enum for mediaton network type   |\n| eventRevenue         | string                                 | event revenue                    |\n| revenueCurrency      | string                                 | revenue currency                 |\n| additionalParameters | Dictionary<string, string>            | Any custom additional parameters |\n|                      |                                        |                                  |\n\n_Example:_\n\n```java\nDictionary<string, string> additionalParams = new Dictionary<string, string>();\nadditionalParams.Add(AFAdRevenueEvent.COUNTRY, \"US\");\nadditionalParams.Add(AFAdRevenueEvent.AD_UNIT, \"89b8c0159a50ebd1\");\nadditionalParams.Add(AFAdRevenueEvent.AD_TYPE, \"Banner\");\nadditionalParams.Add(AFAdRevenueEvent.PLACEMENT, \"place\");\n\nadditionalParams.Add(\"custom\", \"foo\");\nadditionalParams.Add(\"custom_2\", \"bar\");\nadditionalParams.Add(\"af_quantity\", \"1\");\nAppsFlyerAdRevenue.logAdRevenue(\"facebook\",\n                                AppsFlyerAdRevenueMediationNetworkType.AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob,                                   \n                                0.026,\n                                \"USD\",\n                                additionalParams);\n```"
  },
  {
    "path": "docs/conversion-data-unity.md",
    "content": "---\ntitle: Conversion data\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\norder: 4\nhidden: false\n---\n\nIn this guide, you will learn how to get conversion data using [`IAppsFlyerConversionData`](https://dev.appsflyer.com/hc/docs/api#iappsflyerconversiondata), as well as examples for using the conversion data.\n\nLearn more about [what is conversion data](https://dev.appsflyer.com/hc/docs/conversion-data).\n\n## Obtain AppsFlyer conversion data\n\n1. Implement the [`IAppsFlyerConversionData`](https://dev.appsflyer.com/hc/docs/api#iappsflyerconversiondata) class.\n2. Call the [`initSDK`](https://dev.appsflyer.com/hc/docs/api#initsdk) method with `this` as the last parameter.\n3. Use the [`onConversionDataSuccess`](https://dev.appsflyer.com/hc/docs/api#onconversiondatasuccess) method to redirect the user.\n\n## Example\n\n```c#\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData{\n    void Start()\n    {\n        /* AppsFlyer.setDebugLog(true); */\n        AppsFlyer.initSDK(\"devkey\", \"appID\", this);\n        AppsFlyer.startSDK();\n    }\n\n    public void onConversionDataSuccess(string conversionData)\n    {\n        AppsFlyer.AFLog(\"onConversionDataSuccess\", conversionData);\n        Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);\n    }\n\n    public void onConversionDataFail(string error)\n    {\n        AppsFlyer.AFLog(\"onConversionDataFail\", error);\n    }\n\n    public void onAppOpenAttribution(string attributionData)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttribution: This method was replaced by UDL. This is a fake call.\", attributionData);\n    }\n\n    public void onAppOpenAttributionFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttributionFailure: This method was replaced by UDL. This is a fake call.\", error);\n    }\n}\n```\n"
  },
  {
    "path": "docs/purchase-connector.md",
    "content": "---\ntitle: \"Purchase connector\"\nslug: \"purchase-connector-unity\"\ncategory: 5f9705393c689a065c409b23\nparentDoc: 694bc4503a665449be928691\nexcerpt: \"Used to validate and report in-app purchase and subscription revenue events\"\nhidden: false\norder: 2\n---\n\n## Overview\n\nThe AppsFlyer ROI360 purchase connector is used to validate and report in-app purchase and subscription revenue events. It's part of the ROI360 in-app purchase and subscription revenue measurement solution.\n\n- Using the purchase connector requires an ROI360 subscription.\n- If you use this in-app purchase and subscription revenue measurement solution, you shouldn't send [in-app purchase events](https://dev.appsflyer.com/hc/docs/inappevents) with revenue or execute [`validateAndLogInAppPurchase`](https://dev.appsflyer.com/hc/docs/validate-and-log-purchase-ios), as doing so results in duplicate revenue being reported.\n- Before implementing the purchase connector, the ROI360 in-app purchase and subscription revenue measurement needs to be integrated with Google Play and the App Store. [See instructions (steps 1 and 2)](https://support.appsflyer.com/hc/en-us/articles/7459048170769)\n\n## Prerequisites\n\n### iOS Requirements\n- StoreKit SDK v1 or v2 (StoreKit 2 requires iOS 15+)\n- iOS version 9 and higher\n- Unity AppsFlyer plugin **6.17.1** and higher\n\n### Android Requirements\n- Google Play Billing library version **7.x.x** and **8.x.x**\n- Unity AppsFlyer plugin **6.17.1** and higher\n\n### General Requirements\n- Unity version **2020.3** and higher\n- ROI360 subscription\n\n## 📌 Important: Two Versions of Unity Plugin v6.17.7\n\nWe have released **two** versions of the AppsFlyer Unity plugin to support teams at different stages of migrating to **Google Play Billing Library v8.0.0**.\n\n### Option A — `v6.17.7` (Billing Library v8)\n- **What’s included:** Support for **Google Play Billing Library 8.0.0** on Android (Android Purchase Connector version - 2.2.0).\n- **Impact:** This version may introduce **breaking changes** for apps that have **not yet migrated** to the Billing v8 APIs.\n- **Unity IAP requirement:** If you choose this option, update **Unity IAP (`com.unity.purchasing`) to version 5.0.0 or newer** (we recommend the latest 5.x). Unity IAP 4.x does **not** include Billing v8.\n\n### Option B — `v6.17.72` (Billing Library v7)\n- **Purpose:** For developers **not ready** to adopt Billing v8.\n- **Bundled SDKs:** **iOS SDK 6.17.7** and **Android SDK 6.17.3**.\n- **Impact:** Lets you update the AppsFlyer SDKs without changing your existing (pre‑v8) billing integration.\n\n## Installation\n\n### Method 1: Integrated Approach (v6.17.1+) - **Recommended**\n\n**Starting with version 6.17.1, the Purchase Connector is integrated directly into the main AppsFlyer Unity plugin.** You no longer need to download or import a separate package.\n\n1. Download the latest [AppsFlyer Unity plugin](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin) (v6.17.1 or higher)\n2. [Import](https://docs.unity3d.com/Manual/AssetPackages.html) the `appsflyer-unity-plugin-x.x.x.unitypackage` into your Unity project\n   - Go to **Assets** → **Import Package** → **Custom Package**\n   - Select the `appsflyer-unity-plugin-x.x.x.unitypackage`\n\nThe Purchase Connector functionality is now included automatically - no additional imports required!\nIf you previously used the standalone Purchase Connector, simply remove any references to using AppsFlyerConnector; from your codebase, as its functionality is now included in the main plugin.\n\n### Method 2: Separate Repository Approach (Pre-v6.17.1)\n\n**This approach is only relevant for versions prior to 6.17.1.** Starting with version 6.17.1, the Purchase Connector is integrated into the main AppsFlyer Unity plugin and this separate repository approach is no longer needed.\n\nIf you are using a version older than 6.17.1:\n\n1. Download the [AppsFlyer Unity plugin](https://github.com/AppsFlyerSDK/appsflyer-unity-plugin)\n2. Download the [Purchase Connector repository](https://github.com/AppsFlyerSDK/appsflyer-unity-purchase-connector)\n3. Import both packages into your Unity project:\n   - First import `appsflyer-unity-plugin-x.x.x.unitypackage`\n   - Then import `appsflyer-unity-purchase-connector-x.x.x.unitypackage`\n\n**Note:** When using the separate repository approach, make sure the Purchase Connector version is compatible with your AppsFlyer Unity plugin version.\n\n**Recommendation:** Consider upgrading to version 6.17.1+ to use the integrated approach for simplified setup and access to the latest features.\n\n## ProGuard Rules\n\n_Android Only_ - If you are using ProGuard, add the following keep rules to your `proguard-rules.pro` file:\n\n```groovy\n-keep class com.appsflyer.** { *; }\n-keep class kotlin.jvm.internal.Intrinsics{ *; }\n-keep class kotlin.collections.**{ *; }\n-keep class kotlin.Result$Companion { *; }\n```\n\n## Strict Mode Support\n\nThe Purchase Connector supports Strict Mode, which completely removes IDFA collection functionality and AdSupport framework dependencies. Use Strict Mode when developing apps for kids or when IDFA collection is not desired.\n\nMake sure to use the strict mode AppsFlyer Unity plugin along with the Purchase Connector's strict mode functionality.\n\n## Choosing Your Implementation Method\n\n### When to Use Integrated Approach (v6.17.1+)\n✅ **Recommended for:**\n- New projects starting with v6.17.1+\n- Existing projects that can upgrade to v6.17.1+\n- Simplified setup and maintenance\n- Access to latest features like StoreKit 2 support\n\n## Implementation Guide\n\nThe implementation differs slightly depending on which installation method you chose:\n\n### Required Interfaces\n\nYour MonoBehaviour class must implement the following interfaces:\n\n**For Integrated Approach (v6.17.1+):**\n```csharp\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,                    // For conversion data callbacks\n    IAppsFlyerPurchaseValidation,               // For purchase validation callbacks  \n    IAppsFlyerPurchaseRevenueDataSource,        // For StoreKit 1 additional parameters \n    IAppsFlyerPurchaseRevenueDataSourceStoreKit2 // For StoreKit 2 additional parameters \n{\n    // Implementation goes here\n}\n```\n\n**For Separate Repository Approach:**\n```csharp\nusing AppsFlyerSDK;\nusing AppsFlyerConnector; // Additional namespace for separate repository\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,                    // For conversion data callbacks\n    IAppsFlyerPurchaseValidation,               // For purchase validation callbacks  \n    IAppsFlyerPurchaseRevenueDataSource,        // For additional parameters (iOS)\n{\n    // Implementation goes here\n}\n```\n\n### Basic Setup\n\n#### Integrated Approach (v6.17.1+)\n\n```csharp\nusing UnityEngine;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,\n    IAppsFlyerPurchaseValidation,\n    IAppsFlyerPurchaseRevenueDataSource,\n    IAppsFlyerPurchaseRevenueDataSourceStoreKit2\n{\n    [Header(\"AppsFlyer Settings\")]\n    public string devKey = \"YOUR_DEV_KEY\";\n    public string appID = \"YOUR_APP_ID\";\n    public bool isDebug = true;\n    public bool getConversionData = true;\n    \n    void Start()\n    {\n        // 1. Initialize AppsFlyer SDK\n        AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);\n        AppsFlyer.setIsDebug(isDebug);\n        \n        // 2. Initialize Purchase Connector\n        AppsFlyerPurchaseConnector.init(this, Store.GOOGLE);\n        \n        // 3. Configure Purchase Connector\n        ConfigurePurchaseConnector();\n        \n        // 4. Build and start observing\n        AppsFlyerPurchaseConnector.build();\n        AppsFlyerPurchaseConnector.startObservingTransactions();\n        \n        // 5. Start AppsFlyer SDK\n        AppsFlyer.startSDK();\n    }\n    \n    private void ConfigurePurchaseConnector()\n    {\n        // Set sandbox mode for testing\n        AppsFlyerPurchaseConnector.setIsSandbox(true);\n        \n        // Configure StoreKit version (iOS only) - SK1 is the default\n        AppsFlyerPurchaseConnector.setStoreKitVersion(StoreKitVersion.SK2);\n        \n        // Enable automatic logging for subscriptions and in-app purchases\n        AppsFlyerPurchaseConnector.setAutoLogPurchaseRevenue(\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions,\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases\n        );\n        \n        // Enable purchase validation callbacks\n        AppsFlyerPurchaseConnector.setPurchaseRevenueValidationListeners(true);\n        \n        // Set data sources for additional parameters (iOS) - SK1\n        AppsFlyerPurchaseConnector.setPurchaseRevenueDataSource(this);\n        // Set data sources for additional parameters (iOS) - SK2\n        AppsFlyerPurchaseConnector.setPurchaseRevenueDataSourceStoreKit2(this);\n    }\n}\n```\n\n#### Legacy (2-repos) Approach\n\n```csharp\nusing UnityEngine;\nusing AppsFlyerSDK;\nusing AppsFlyerConnector;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,\n    IAppsFlyerPurchaseValidation,\n    IAppsFlyerPurchaseRevenueDataSource\n{\n    [Header(\"AppsFlyer Settings\")]\n    public string devKey = \"YOUR_DEV_KEY\";\n    public string appID = \"YOUR_APP_ID\";\n    public bool isDebug = true;\n    public bool getConversionData = true;\n    \n    void Start()\n    {\n        // 1. Initialize AppsFlyer SDK\n        AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);\n        AppsFlyer.setIsDebug(isDebug);\n        \n        // 2. Initialize Purchase Connector (using AppsFlyerConnector namespace)\n        AppsFlyerPurchaseConnector.init(this, AppsFlyerConnector.Store.GOOGLE);\n        \n        // 3. Configure Purchase Connector\n        ConfigurePurchaseConnector();\n        \n        // 4. Build and start observing\n        AppsFlyerPurchaseConnector.build();\n        AppsFlyerPurchaseConnector.startObservingTransactions();\n        \n        // 5. Start AppsFlyer SDK\n        AppsFlyer.startSDK();\n    }\n    \n    private void ConfigurePurchaseConnector()\n    {\n        // Set sandbox mode for testing\n        AppsFlyerPurchaseConnector.setIsSandbox(true);\n        \n        // Enable automatic logging for subscriptions and in-app purchases\n        AppsFlyerPurchaseConnector.setAutoLogPurchaseRevenue(\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions,\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases\n        );\n        \n        // Enable purchase validation callbacks\n        AppsFlyerPurchaseConnector.setPurchaseRevenueValidationListeners(true);\n        \n    }\n}\n```\n\n## Core APIs\n\n### Initialization\n\n```csharp\n// Initialize Purchase Connector with store type\nAppsFlyerPurchaseConnector.init(this, Store.GOOGLE);\n```\n\n### Configuration Options\n\n#### StoreKit Version (iOS Only)\n```csharp\n// Set StoreKit version - SK1 or SK2\nAppsFlyerPurchaseConnector.setStoreKitVersion(StoreKitVersion.SK2);\n```\n\n#### Sandbox Mode\n```csharp\n// Enable sandbox mode for testing\nAppsFlyerPurchaseConnector.setIsSandbox(true);\n```\n\n#### Auto-Logging Options\n```csharp\n// Enable automatic logging for specific purchase types\nAppsFlyerPurchaseConnector.setAutoLogPurchaseRevenue(\n    AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions,\n    AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases\n);\n```\n\n**Available Options:**\n- `AppsFlyerAutoLogPurchaseRevenueOptionsDisabled`: Disable automatic logging\n- `AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions`: Log auto-renewable subscriptions\n- `AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases`: Log in-app purchases\n\n### Transaction Observation\n\n```csharp\n// Start observing transactions\nAppsFlyerPurchaseConnector.startObservingTransactions();\n\n// Stop observing transactions\nAppsFlyerPurchaseConnector.stopObservingTransactions();\n```\n\n### Build and Complete Setup\n\n```csharp\n// Build the Purchase Connector with all configurations\nAppsFlyerPurchaseConnector.build();\n```\n\n## Interface Implementations\n### IAppsFlyerPurchaseValidation\n\n```csharp\npublic void didReceivePurchaseRevenueValidationInfo(string validationInfo)\n{\n    AppsFlyer.AFLog(\"didReceivePurchaseRevenueValidationInfo\", validationInfo);\n    Debug.Log(\"Purchase validation success: \" + validationInfo);\n    \n    // Handle different purchase types on Android\n#if UNITY_ANDROID\n    if (dictionary.ContainsKey(\"productPurchase\") && dictionary[\"productPurchase\"] != null)\n    {\n        // Handle in-app purchase validation result\n        Debug.Log(\"In-app purchase validated\");\n    }\n    else if (dictionary.ContainsKey(\"subscriptionPurchase\") && dictionary[\"subscriptionPurchase\"] != null)\n    {\n        // Handle subscription validation result  \n        Debug.Log(\"Subscription validated\");\n    }\n#endif\n}\n\npublic void didReceivePurchaseRevenueError(string error)\n{\n    AppsFlyer.AFLog(\"didReceivePurchaseRevenueError\", error);\n    Debug.LogError(\"Purchase validation error: \" + error);\n}\n```\n\n### IAppsFlyerPurchaseRevenueDataSource (StoreKit 1)\n\n```csharp\npublic Dictionary<string, object> PurchaseRevenueAdditionalParametersForProducts(\n    HashSet<object> products, \n    HashSet<object> transactions)\n{\n    // Add custom parameters to purchase events\n    return new Dictionary<string, object>\n    {\n        [\"custom_param_1\"] = \"value1\",\n        [\"custom_param_2\"] = \"value2\",\n        [\"user_level\"] = 5,\n        [\"purchase_source\"] = \"main_store\"\n    };\n}\n```\n\n### IAppsFlyerPurchaseRevenueDataSourceStoreKit2 (StoreKit 2)\n\n```csharp\npublic Dictionary<string, object> PurchaseRevenueAdditionalParametersStoreKit2ForProducts(\n    HashSet<object> products, \n    HashSet<object> transactions)\n{\n    // Add custom parameters specifically for StoreKit 2 purchases\n    return new Dictionary<string, object>\n    {\n        [\"sk2_custom_param\"] = \"sk2_value\"\n    };\n}\n```\n\n## Advanced Features\n\n### StoreKit 2 Consumable Transactions (iOS 15+ to iOS 18+)\n\nOn iOS 15 and above, consumable in-app purchases are handled via StoreKit 2.  \n- **On iOS 18 and later:**  \n  Apple introduced a new Info.plist flag: `SKIncludeConsumableInAppPurchaseHistory`.  \n  - If you set `SKIncludeConsumableInAppPurchaseHistory` to `YES` in your Info.plist, automatic collection will happen.\n  - If the flag is not present or is set to `NO`, you must manually log consumable transactions as shown below.\n\n- **On iOS 15–18:**  \n  Consumable purchases must always be logged manually.\n\n```csharp\n    AppsFlyerPurchaseConnector.logConsumableTransaction(transactionId); //(iOS SK2 only)\n\n```\n  \n### Custom Purchase Validation Callbacks\n\nEnable validation callbacks to receive detailed purchase information:\n\n```csharp\nAppsFlyerPurchaseConnector.setPurchaseRevenueValidationListeners(true);\n```\n\n## Testing in Sandbox\n\n### iOS Testing\n1. Set sandbox mode: `AppsFlyerPurchaseConnector.setIsSandbox(true)`\n2. Use TestFlight sandbox accounts for testing\n3. Test on real devices with Xcode\n\n### Android Testing  \n1. Set sandbox mode: `AppsFlyerPurchaseConnector.setIsSandbox(true)`\n2. Follow [Google Play Billing testing guidelines](https://developer.android.com/google/play/billing/test)\n3. Use test accounts and test products\n\n> **⚠️ IMPORTANT**: Remove `setIsSandbox(true)` or set it to `false` before releasing to production. Production purchases sent in sandbox mode will not be validated properly!\n\n## Complete Implementation Examples\n\n### Integrated Approach (v6.17.1+)\n\n```csharp\nusing System.Collections.Generic;\nusing UnityEngine;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,\n    IAppsFlyerPurchaseValidation,\n    IAppsFlyerPurchaseRevenueDataSource,\n    IAppsFlyerPurchaseRevenueDataSourceStoreKit2\n{\n    [Header(\"AppsFlyer Configuration\")]\n    public string devKey = \"YOUR_DEV_KEY\";\n    public string appID = \"YOUR_APP_ID\";\n    public string UWPAppID = \"YOUR_UWP_APP_ID\";\n    public string macOSAppID = \"YOUR_MACOS_APP_ID\";\n    public bool isDebug = true;\n    public bool getConversionData = true;\n\n    void Start()\n    {\n        // 1. Initialize AppsFlyer SDK\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n        AppsFlyer.initSDK(devKey, UWPAppID, getConversionData ? this : null);\n#elif UNITY_STANDALONE_OSX && !UNITY_EDITOR\n        AppsFlyer.initSDK(devKey, macOSAppID, getConversionData ? this : null);\n#else\n        AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);\n#endif\n\n        AppsFlyer.setIsDebug(isDebug);\n\n        // 2. Initialize and configure Purchase Connector\n        AppsFlyerPurchaseConnector.init(this, Store.GOOGLE);\n        AppsFlyerPurchaseConnector.setStoreKitVersion(StoreKitVersion.SK2);\n        AppsFlyerPurchaseConnector.setIsSandbox(true); // Remove for production\n        \n        AppsFlyerPurchaseConnector.setAutoLogPurchaseRevenue(\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions,\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases\n        );\n        \n        AppsFlyerPurchaseConnector.setPurchaseRevenueValidationListeners(true);\n        AppsFlyerPurchaseConnector.setPurchaseRevenueDataSource(this);\n        AppsFlyerPurchaseConnector.setPurchaseRevenueDataSourceStoreKit2(this);\n\n        // 3. Build and start\n        AppsFlyerPurchaseConnector.build();\n        AppsFlyerPurchaseConnector.startObservingTransactions();\n\n        // 4. Start AppsFlyer SDK\n        AppsFlyer.startSDK();\n        \n        Debug.Log(\"AppsFlyer SDK + Purchase Connector initialized successfully\");\n    }\n\n    // --- Purchase Revenue Data Sources ---\n    public Dictionary<string, object> PurchaseRevenueAdditionalParametersForProducts(\n        HashSet<object> products, \n        HashSet<object> transactions)\n    {\n        return new Dictionary<string, object>\n        {\n            [\"storekit_version\"] = \"1.0\",\n            [\"additional_param\"] = \"sk1_value\",\n            [\"product_count\"] = products.Count,\n            [\"transaction_count\"] = transactions.Count\n        };\n    }\n\n    public Dictionary<string, object> PurchaseRevenueAdditionalParametersStoreKit2ForProducts(\n        HashSet<object> products, \n        HashSet<object> transactions)\n    {\n        return new Dictionary<string, object>\n        {\n            [\"storekit_version\"] = \"2.0\", \n            [\"additional_param\"] = \"sk2_value\",\n            [\"product_count\"] = products.Count,\n            [\"transaction_count\"] = transactions.Count\n        };\n    }\n\n    // --- Purchase Validation Callbacks ---\n    public void didReceivePurchaseRevenueValidationInfo(string validationInfo)\n    {\n        AppsFlyer.AFLog(\"didReceivePurchaseRevenueValidationInfo\", validationInfo);\n        Debug.Log(\"Purchase validation success: \" + validationInfo);\n        \n        // Parse and handle validation info\n        var dict = AFMiniJSON.Json.Deserialize(validationInfo) as Dictionary<string, object>;\n        \n#if UNITY_ANDROID\n        if (dict.ContainsKey(\"productPurchase\"))\n        {\n            Debug.Log(\"Android in-app purchase validated\");\n        }\n        else if (dict.ContainsKey(\"subscriptionPurchase\"))\n        {\n            Debug.Log(\"Android subscription validated\");\n        }\n#endif\n    }\n\n    public void didReceivePurchaseRevenueError(string error)\n    {\n        AppsFlyer.AFLog(\"didReceivePurchaseRevenueError\", error);\n        Debug.LogError(\"Purchase validation error: \" + error);\n    }\n\n    // --- Conversion Data Callbacks ---\n    public void onConversionDataSuccess(string conversionData)\n    {\n        AppsFlyer.AFLog(\"onConversionDataSuccess\", conversionData);\n        var dict = AppsFlyer.CallbackStringToDictionary(conversionData);\n        // Handle deferred deep linking\n    }\n\n    public void onConversionDataFail(string error)\n    {\n        AppsFlyer.AFLog(\"onConversionDataFail\", error);\n    }\n\n    public void onAppOpenAttribution(string attributionData)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttribution\", attributionData);\n        var dict = AppsFlyer.CallbackStringToDictionary(attributionData);\n        // Handle direct deep linking\n    }\n\n    public void onAppOpenAttributionFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttributionFailure\", error);\n    }\n}\n```\n\n### Legacy Approach\n\n```csharp\nusing System.Collections.Generic;\nusing UnityEngine;\nusing AppsFlyerSDK;\nusing AppsFlyerConnector;\n\npublic class AppsFlyerObjectScript : MonoBehaviour, \n    IAppsFlyerConversionData,\n    IAppsFlyerPurchaseValidation,\n    IAppsFlyerPurchaseRevenueDataSource,\n    IAppsFlyerPurchaseRevenueDataSourceStoreKit2\n{\n    [Header(\"AppsFlyer Configuration\")]\n    public string devKey = \"YOUR_DEV_KEY\";\n    public string appID = \"YOUR_APP_ID\";\n    public string UWPAppID = \"YOUR_UWP_APP_ID\";\n    public string macOSAppID = \"YOUR_MACOS_APP_ID\";\n    public bool isDebug = true;\n    public bool getConversionData = true;\n\n    void Start()\n    {\n        // 1. Initialize AppsFlyer SDK\n#if UNITY_WSA_10_0 && !UNITY_EDITOR\n        AppsFlyer.initSDK(devKey, UWPAppID, getConversionData ? this : null);\n#elif UNITY_STANDALONE_OSX && !UNITY_EDITOR\n        AppsFlyer.initSDK(devKey, macOSAppID, getConversionData ? this : null);\n#else\n        AppsFlyer.initSDK(devKey, appID, getConversionData ? this : null);\n#endif\n\n        AppsFlyer.setIsDebug(isDebug);\n\n        // 2. Initialize and configure Purchase Connector (using separate repository approach)\n        AppsFlyerPurchaseConnector.init(this, AppsFlyerConnector.Store.GOOGLE);\n        AppsFlyerPurchaseConnector.setIsSandbox(true); // Remove for production\n        \n        AppsFlyerPurchaseConnector.setAutoLogPurchaseRevenue(\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsAutoRenewableSubscriptions,\n            AppsFlyerAutoLogPurchaseRevenueOptions.AppsFlyerAutoLogPurchaseRevenueOptionsInAppPurchases\n        );\n        \n        AppsFlyerPurchaseConnector.setPurchaseRevenueValidationListeners(true);\n\n        // 3. Build and start\n        AppsFlyerPurchaseConnector.build();\n        AppsFlyerPurchaseConnector.startObservingTransactions();\n\n        // 4. Start AppsFlyer SDK\n        AppsFlyer.startSDK();\n        \n        Debug.Log(\"AppsFlyer SDK + Purchase Connector (separate repository) initialized successfully\");\n    }\n\n    // --- Purchase Revenue Data Sources ---\n    public Dictionary<string, object> PurchaseRevenueAdditionalParametersForProducts(\n        HashSet<object> products, \n        HashSet<object> transactions)\n    {\n        return new Dictionary<string, object>\n        {\n            [\"implementation_type\"] = \"separate_repository\",\n            [\"additional_param\"] = \"value\",\n            [\"product_count\"] = products.Count,\n            [\"transaction_count\"] = transactions.Count\n        };\n    }\n\n    public Dictionary<string, object> PurchaseRevenueAdditionalParametersStoreKit2ForProducts(\n        HashSet<object> products, \n        HashSet<object> transactions)\n    {\n        // Note: StoreKit 2 support depends on Purchase Connector version\n        return new Dictionary<string, object>\n        {\n            [\"implementation_type\"] = \"separate_repository_sk2\",\n            [\"additional_param\"] = \"sk2_value\",\n            [\"product_count\"] = products.Count,\n            [\"transaction_count\"] = transactions.Count\n        };\n    }\n\n    // --- Purchase Validation Callbacks ---\n    public void didReceivePurchaseRevenueValidationInfo(string validationInfo)\n    {\n        AppsFlyer.AFLog(\"didReceivePurchaseRevenueValidationInfo\", validationInfo);\n        Debug.Log(\"Purchase validation success: \" + validationInfo);\n        \n        // Parse and handle validation info\n        var dict = AFMiniJSON.Json.Deserialize(validationInfo) as Dictionary<string, object>;\n        \n#if UNITY_ANDROID\n        if (dict.ContainsKey(\"productPurchase\"))\n        {\n            Debug.Log(\"Android in-app purchase validated\");\n        }\n        else if (dict.ContainsKey(\"subscriptionPurchase\"))\n        {\n            Debug.Log(\"Android subscription validated\");\n        }\n#endif\n    }\n\n    public void didReceivePurchaseRevenueError(string error)\n    {\n        AppsFlyer.AFLog(\"didReceivePurchaseRevenueError\", error);\n        Debug.LogError(\"Purchase validation error: \" + error);\n    }\n\n    // --- Conversion Data Callbacks ---\n    public void onConversionDataSuccess(string conversionData)\n    {\n        AppsFlyer.AFLog(\"onConversionDataSuccess\", conversionData);\n        var dict = AppsFlyer.CallbackStringToDictionary(conversionData);\n        // Handle deferred deep linking\n    }\n\n    public void onConversionDataFail(string error)\n    {\n        AppsFlyer.AFLog(\"onConversionDataFail\", error);\n    }\n\n    public void onAppOpenAttribution(string attributionData)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttribution\", attributionData);\n        var dict = AppsFlyer.CallbackStringToDictionary(attributionData);\n        // Handle direct deep linking\n    }\n\n    public void onAppOpenAttributionFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onAppOpenAttributionFailure\", error);\n    }\n}\n```\n\n## Migration Guide\n\n### Migrating from Legacy to Integrated (Recommended)\n\nIf you're upgrading from the separate repository approach to the integrated approach:\n\n1. **Backup your project** before making changes\n2. **Remove old Purchase Connector package**: Delete the old Purchase Connector files from your project\n3. **Update AppsFlyer Unity plugin**: Install AppsFlyer Unity plugin v6.17.1 or higher\n4. **Update code changes**:\n   ```csharp\n   // OLD (Separate Repository)\n   using AppsFlyerConnector; //Remove\n   \n   // NEW (Integrated)\n   using AppsFlyerSDK; // Only this namespace needed\n   AppsFlyerPurchaseConnector.init(this, Store.GOOGLE);\n   ```\n5. **Test thoroughly**: Verify all Purchase Connector functionality works as expected\n6. **Update documentation/comments**: Remove references to separate repository setup\n"
  },
  {
    "path": "docs/purchase-validation-unity.md",
    "content": "---\ntitle: \"Purchase and subscription validation\"\nslug: \"purchase-subscription-validation-unity\"\ncategory: 5f9705393c689a065c409b23\nparentDoc: 6370c9e2441a4504d6bca3bd\nhidden: false\norder: 13\n---\nPurchase validation ensures that only real, store-confirmed in-app purchases and subscriptions are measured in AppsFlyer. It improves revenue accuracy, helps prevent reporting errors, and supports better campaign decisions.\n\nAppsFlyer offers two products to support purchase validation:\n\n- **Receipt validation** – A free, lightweight solution for basic in-app purchase verification.\n- **ROI360 Store revenue** – A premium, comprehensive solution for full revenue accuracy, including subscription lifecycle coverage and net revenue reporting.\n\nFor more information, see [Purchase and subscription validation](https://support.appsflyer.com/hc/en-us/articles/42120228484241--WIP-Purchase-and-subscription-validation-Overview).\n\n## SDK Integration Methods\n\nAppsFlyer supports two SDK integration methods for sending in-app purchase data to AppsFlyer for validation:\n\n### 1. Manual Integration method – Validate and Log\n\nCall Validate and Log (`validateAndSendInAppPurchase`) every time a transaction occurs in the app (such as an in-app purchase, subscription start, or trial start). The method sends the transaction to AppsFlyer, which validates it with the store and generates the relevant in-app event.\n\n- Requires an explicit call from the app for every transaction\n- Suitable for apps that need to capture events not included in the Purchase Connector’s default coverage. With the Validate and log method, developers can explicitly target and send these additional events.\n\nTo get started see: [`Validate and Log`](https://dev.appsflyer.com/hc/docs/validate-and-log-unity)\n\n\n### 2. Automated Integration method – Purchase Connector\n\nPurchase Connector automatically detects in-app purchases and subscriptions made on the device. Once initialized, it sends the required data to AppsFlyer without additional logging code.\n\n- Supported only by ROI360 products and recommended for most apps\n- Triggers validation automatically and returns the result to the client in real time\n- The following capabilities cannot be supported through simple customization of the Validate and Log method and therefore require Purchase Connector:\n    - Logging subscription revenue from users who subscribed before the integration was added.\n    - Logging subscription price changes, ensuring revenue reflects updated pricing.\n\nTo get started see: [Unity purchase SDK connector](https://dev.appsflyer.com/hc/docs/purchase-connector-unity)\n\n\n---\n> ⚠️ Important\n> \n> To avoid duplicate event logging and inconsistent validation results, it’s recommended to use only one integration method per application.\n"
  },
  {
    "path": "docs/validate-and-log-unity.md",
    "content": "---\ntitle: \"Validate and log purchase\"\nslug: \"validate-and-log-unity\"\ncategory: 5f9705393c689a065c409b23\nparentDoc: 694bc4503a665449be928691\nexcerpt: \"Used to validate and report in-app purchase and subscription revenue events\"\nhidden: false\norder: 1\n---\n\n## Validate and log purchase\n\nFollow the instructions according to your operating system.\n\nCalling `validateAndSendInAppPurchase` automatically generates an `af_purchase` in-app event, so you don't need to send this event yourself.\nThe validate purchase response is triggered in the `AppsFlyerTrackerCallbacks.cs` class.\n\n```c#\n// for Android \n`void validateAndSendInAppPurchase(AFPurchaseDetailsAndroid details, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`\n// for iOS \n`void validateAndSendInAppPurchase(AFSDKPurchaseDetailsIOS details, Dictionary<string, string> extraEventValues, MonoBehaviour gameObject)`\n\n```\n\n```c#\nusing UnityEngine.Purchasing;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObject : MonoBehaviour, IAppsFlyerValidateAndLog\n{\n\n    public static string kProductIDConsumable = \"com.test.cons\";\n\n    void Start()\n    {\n        AppsFlyer.initSDK(\"devKey\", \"devKey\");\n        AppsFlyer.startSDK();\n    }\n\n    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n    {\n        string prodID = args.purchasedProduct.definition.id;\n        string price = args.purchasedProduct.metadata.localizedPrice.ToString();\n        string currency = args.purchasedProduct.metadata.isoCurrencyCode;\n\n        string receipt = args.purchasedProduct.receipt;\n        var recptToJSON = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize(product.receipt);\n        var receiptPayload = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize((string)recptToJSON[\"Payload\"]);\n        var transactionID = product.transactionID;\n\n        if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal))\n        {\n#if UNITY_IOS\n\n            if(isSandbox)\n            {\n                AppsFlyeriOS.setUseReceiptValidationSandbox(true);\n            }\n\n            AFSDKPurchaseDetailsIOS details = AFSDKPurchaseDetailsIOS.Init(prodID, price, currency, transactionID);\n\n            AppsFlyeriOS.validateAndSendInAppPurchase(details, null, this);\n#elif UNITY_ANDROID\n\n        AFPurchaseDetailsAndroid details = new AFPurchaseDetailsAndroid(AFPurchaseType.Subscription, \"token\", prodID, price, currency);\n\n        AppsFlyerAndroid.validateAndSendInAppPurchase(\n        details,\n        null, \n        this);\n#endif\n        }\n\n        return PurchaseProcessingResult.Complete;\n    }\n\n    public void onValidateAndLogComplete(string result)\n    {\n        AppsFlyer.AFLog(\"onValidateAndLogComplete\", result);\n        Dictionary<string, object> validateAndLogDataDictionary = AppsFlyer.CallbackStringToDictionary(result);\n    }\n\n    public void onValidateAndLogFailure(string error)\n    {\n        AppsFlyer.AFLog(\"onValidateAndLogFailure\", error);\n        Dictionary<string, object> validateAndLogErrorDictionary = AppsFlyer.CallbackStringToDictionary(error);\n    }\n\n}\n\n```\n\n## Receipt validation [Legacy]\n<span class=\"annotation-deprecated\">Deprecated since V6.17.8</span>  \n\n\nFor Receipt Validation, follow the instructions according to your operating system.\n\n**Notes**\nCalling validateReceipt automatically generates an `af_purchase` in-app event, so you don't need to send this event yourself.\nThe validate purchase response is triggered in the `AppsFlyerTrackerCallbacks.cs` class.\n\n`void validateAndSendInAppPurchase(string productIdentifier, string price, string currency, string tranactionId, Dictionary<string, string> additionalParameters, MonoBehaviour gameObject)`\n\n```c#\n//To get the callbacks\n//AppsFlyer.createValidateInAppListener (\"AppsFlyerTrackerCallbacks\", \"onInAppBillingSuccess\", \"onInAppBillingFailure\");\nAppsFlyer.validateReceipt(string publicKey, string purchaseData, string signature, string price, string currency, Dictionary additionalParametes);\n```\n\n```c#\nusing UnityEngine.Purchasing;\nusing AppsFlyerSDK;\n\npublic class AppsFlyerObject : MonoBehaviour, IStoreListener, IAppsFlyerValidateReceipt\n{\n\n    public static string kProductIDConsumable = \"com.test.cons\";\n\n    void Start()\n    {\n        AppsFlyer.initSDK(\"devKey\", \"devKey\");\n        AppsFlyer.startSDK();\n    }\n\n    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n    {\n        string prodID = args.purchasedProduct.definition.id;\n        string price = args.purchasedProduct.metadata.localizedPrice.ToString();\n        string currency = args.purchasedProduct.metadata.isoCurrencyCode;\n\n        string receipt = args.purchasedProduct.receipt;\n        var recptToJSON = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize(product.receipt);\n        var receiptPayload = (Dictionary<string, object>)AFMiniJSON.Json.Deserialize((string)recptToJSON[\"Payload\"]);\n        var transactionID = product.transactionID;\n\n        if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal))\n        {\n#if UNITY_IOS\n\n            if(isSandbox)\n            {\n                AppsFlyeriOS.setUseReceiptValidationSandbox(true);\n            }\n\n            AppsFlyeriOS.validateAndSendInAppPurchase(prodID, price, currency, transactionID, null, this);\n#elif UNITY_ANDROID\n        var purchaseData = (string)receiptPayload[\"json\"];\n        var signature = (string)receiptPayload[\"signature\"];\n        AppsFlyerAndroid.validateAndSendInAppPurchase(\n        \"<google_public_key>\", \n        signature, \n        purchaseData, \n        price, \n        currency, \n        null, \n        this);\n#endif\n        }\n\n        return PurchaseProcessingResult.Complete;\n    }\n\n    public void didFinishValidateReceipt(string result)\n    {\n        AppsFlyer.AFLog(\"didFinishValidateReceipt\", result);\n    }\n\n    public void didFinishValidateReceiptWithError(string error)\n    {\n        AppsFlyer.AFLog(\"didFinishValidateReceiptWithError\", error);\n    }\n\n}\n\n```\n\n\n"
  },
  {
    "path": "obj/Debug/.NETFramework,Version=v4.7.1.AssemblyAttributes.cs",
    "content": "// <autogenerated />\nusing System;\nusing System.Reflection;\n[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(\".NETFramework,Version=v4.7.1\", FrameworkDisplayName = \".NET Framework 4.7.1\")]\n"
  },
  {
    "path": "strict-mode-sdk/strictMode.md",
    "content": "## Strict Mode SDK\n\n\n* Use the [strict mode SDK](https://support.appsflyer.com/hc/en-us/articles/360001422989-User-opt-in-opt-out-in-the-AppsFlyer-SDK#strict-mode-sdk) to completely remove IDFA collection functionality and AdSupport framework dependencies (for example, when developing apps for kids).\n* [Strict mode](https://support.appsflyer.com/hc/en-us/articles/207032066-iOS-SDK-V6-X-integration-guide-for-developers#integration-strict-mode-sdk) SDK used pod `pod 'AppsFlyerFramework/Strict','6.1.3'`\n* In addition the following API are removed: `disableAdvertisingIdentifier` and `waitForATTUserAuthorizationWithTimeoutInterval`\n* To implement strict mode use the appsflyer-unity-plugin-\\*.\\*.\\*-strict-mode.unitypackage"
  }
]